Communitygithub.com

remix-run/react-router-framework-mode

Construa aplicações React full-stack usando o modo framework do React Router. Utilize ao configurar rotas, trabalhar com loaders e actions, lidar com formulários, navegação, UI pendente/otimista, limites de erro ou ao trabalhar com react-router.config.ts ou outras convenções do React Router.

O que é react-router-framework-mode?

Este skill capacita agentes de IA a construir aplicações React full-stack utilizando o **modo framework** do React Router. Diferente do uso tradicional como biblioteca de roteamento client-side, o modo framework adiciona recursos de servidor como loaders para carregamento de dados, actions para manipulação de formulários e mutations, e suporte a formulários HTML progressivos. A partir da configuração central em `react-router.config.ts`, o agente pode definir rotas com componentes, loaders e actions, além de gerenciar estados de navegação como UI pendente (durante carregamento) e otimista (para respostas rápidas). O skill também cobre boundaries de erro para tratamento de exceções e convenções de diretório e nomeação de arquivos. É ideal para agentes que atuam em projetos React Router modernos (versão 7+), fornecendo um guia completo de como estruturar e implementar funcionalidades full-stack de forma declarativa e eficiente.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/remix-run/agent-skills/tree/main/skills/react-router-framework-mode

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

O que react-router-framework-mode faz?

Construa aplicações React full-stack usando o modo framework do React Router. Utilize ao configurar rotas, trabalhar com loaders e actions, lidar com formulários, navegação, UI pendente/otimista, limites de erro ou ao trabalhar com react-router.config.ts ou outras convenções do React Router.

Visão Geral

O modo framework do React Router estende o roteador para oferecer recursos de servidor como carregamento de dados (loaders), manipulação de formulários (actions), e formulários HTML progressivos. Ele permite que você construa aplicações full-stack com React de forma declarativa.

Configuração

O arquivo react-router.config.ts na raiz do projeto define as configurações do modo framework:

import { type Config } from "@react-router/dev/config";

export default {
  appDirectory: "app",
  future: {
    unstable_optimizeDeps: true,
  },
} satisfies Config;

Rotas

As rotas são definidas usando o sistema de arquivos no diretório app/routes/ ou manualmente via plugin.

Exemplo de Rota

// app/routes/contacts.$contactId.tsx
import { type LoaderFunctionArgs } from "react-router";
import { getContact } from "../data";

export async function loader({ params }: LoaderFunctionArgs) {
  const contact = await getContact(params.contactId);
  return { contact };
}

export default function Contact() {
  // Componente da rota
}

Loaders e Actions

  • Loaders: Funções que fornecem dados para a rota. Elas rodam no servidor e são chamadas antes da renderização.
  • Actions: Funções que manipulam dados (POST, PUT, PATCH, DELETE). Elas processam formulários e mutations.

Formulários

Use o componente <Form> do React Router para enviar dados com suporte a JavaScript desabilitado:

import { Form } from "react-router";

export default function NewContact() {
  return (
    <Form method="post">
      <input name="name" />
      <button type="submit">Salvar</button>
    </Form>
  );
}

Navegação e UI

  • Navegação: Use <Link> para navegação client-side.
  • UI Pendente: Mostre um indicador enquanto a navegação está carregando usando o hook useNavigation.
import { useNavigation } from "react-router";

function SubmitButton() {
  const navigation = useNavigation();
  return (
    <button type="submit" disabled={navigation.state === "submitting"}>
      {navigation.state === "submitting" ? "Enviando..." : "Enviar"}
    </button>
  );
}
  • UI Otimista: Atualize a interface imediatamente antes da confirmação do servidor usando useFetcher.

Limites de Erro

Defina componentes de erro para capturar exceções:

export function ErrorBoundary() {
  return (
    <div>
      <h1>Erro</h1>
      <p>Algo deu errado.</p>
    </div>
  );
}

Convenções

  • Diretório app/: Contém todo o código da aplicação.
  • Arquivo root.tsx: Layout raiz da aplicação.
  • Pasta routes/: Rotas da aplicação.
  • Pasta data/: Lógica de acesso a dados.
  • Pasta styles/: Folhas de estilo.

Exemplo Completo

// app/routes/contacts.$contactId.tsx
import { Form, useLoaderData, useFetcher } from "react-router";
import { getContact, updateContact } from "../data";
import type { LoaderFunctionArgs, ActionFunctionArgs } from "react-router";

export async function loader({ params }: LoaderFunctionArgs) {
  const contact = await getContact(params.contactId);
  if (!contact) {
    throw new Response("Not Found", { status: 404 });
  }
  return { contact };
}

export async function action({ request, params }: ActionFunctionArgs) {
  const formData = await request.formData();
  return updateContact(params.contactId, {
    favorite: formData.get("favorite") === "true",
  });
}

export default function Contact() {
  const { contact } = useLoaderData<typeof loader>();
  const fetcher = useFetcher();

  return (
    <div id="contact">
      <h1>{contact.name}</h1>
      <fetcher.Form method="post">
        <button
          name="favorite"
          value={contact.favorite ? "false" : "true"}
        >
          {contact.favorite ? "★" : "☆"}
        </button>
      </fetcher.Form>
    </div>
  );
}

Recursos Adicionais

Habilidades Relacionadas