Pular para o conteúdo principal

Routes

O template inclui um Route Registry — um registro central que mapeia a URL de cada página da aplicação. A sua marca pode renomear qualquer URL sem tocar em componente nem na árvore de rotas.

Como funciona

Três arquivos formam o sistema:

ArquivoPapel
app/types/routes.tsInterface RoutePathMap — a lista autoritativa de chaves de rota (59 hoje).
app/config/routes/paths.tsOs paths default (routePaths). É este arquivo que você sobrescreve.
app/router/routes.tsA árvore de rotas do React Router; lê os paths via routePattern().
// app/config/routes/paths.ts (trecho dos defaults)
import type { RoutePathMap } from "../../types/routes";

export const routePaths: RoutePathMap = {
home: "/",
search: "/search",
casino: "/games",
"casino.play": "/games/:provider/:game",
sports: "/sports",
gamification: "/vip",
"user.data": "/user/data",
// ... (ver a lista completa abaixo)
};

Como todos os links da aplicação são gerados por routeHref() / gameHref() e a árvore de rotas usa routePattern(), mudar o mapa de paths atualiza roteamento e navegação de uma vez.

observação

app/routes.ts na raiz do app/ tem só quatro linhas — ele exporta buildRoutes(), que monta a árvore de fato em app/router/routes.ts.

Customizando as URLs da sua marca

  1. Copie app/config/routes/paths.ts para overrides/<brand-key>/app/config/routes/paths.ts.
  2. Altere apenas os segmentos estáticos dos paths.
  3. Não renomeie os placeholders de parâmetro (:slug, :provider, :game, :id, :type, :token) — os componentes leem useParams() com esses nomes exatos.

O <brand-key> é derivado do ORIGIN_DOMAIN (minúsculo, pontos viram hífens): minhamarca.comminhamarca-com.

:::danger Override é substituição do arquivo inteiro, e o mapa precisa estar completo O sistema de override não faz deep-merge — se o arquivo existe no diretório da sua marca, ele substitui o do base por completo, sem fallback campo-a-campo. Além disso, routePaths é tipado como RoutePathMap, então o TypeScript exige todas as 59 chaves: um mapa parcial não compila.

Por isso a instrução é copiar o arquivo base inteiro e editar os valores. Comece de um arquivo completo e você nunca cai nesse erro. :::

Exemplo (trecho)

// overrides/minhamarca-com/app/config/routes/paths.ts
import type { RoutePathMap } from "~/types/routes";

export const routePaths: RoutePathMap = {
home: "/",
search: "/buscar",
"search.casino": "/buscar/cassino",
"search.sports": "/buscar/esportes",

casino: "/cassino",
"casino.live": "/cassino/ao-vivo",
"casino.category": "/cassino/categoria/:slug",
"casino.providers": "/cassino/provedores",
"casino.provider": "/cassino/provedores/:slug",
"casino.play": "/cassino/jogo/:provider/:game",

sports: "/esportes",
"sports.catchAll": "/esportes/*",
"sports.test": "/esportes-teste",

gamification: "/vip",
"gamification.missions": "/vip/missoes",
// ... e assim por diante
};
cuidado

O bloco acima é um trecho ilustrativo, não um arquivo válido. O arquivo real precisa declarar as 59 chaves — copie app/config/routes/paths.ts como base.

Chaves de rota disponíveis

A lista abaixo reflete app/config/routes/paths.ts. Se divergir, o arquivo é a verdade — chaves novas são adicionadas em app/types/routes.ts.

Home e busca

ChavePath default
home/
search/search
search.casino/search/casino
search.sports/search/sports
debug/debug
favorites/favorites
recents/recents

Cassino

ChavePath default
casino/games
casino.live/games/live
casino.category/games/category/:slug
casino.providers/games/providers
casino.provider/games/providers/:slug
casino.play/games/:provider/:game

Esportes

ChavePath default
sports/sports
sports.catchAll/sports/*
sports.test/sports-test

Gamificação

ChavePath default
gamification/vip
gamification.missions/vip/missions
gamification.tournaments/vip/tournaments
gamification.tournament/vip/tournaments/:id
gamification.store/vip/store
gamification.miniGames/vip/mini-games
gamification.levels/vip/levels
gamification.badges/vip/badges
gamification.bonuses/vip/bonuses

Conta do usuário

ChavePath default
user.data/user/data
user.wallet/user/wallet
user.history/user/history
user.config/user/config
user.protection/user/protection
user.notifications/user/notifications
user.validate/user/validate/:type/:token
user.refers/user/refers
user.rewards/user/rewards
user.incomeReport/user/income-report

Páginas legais

ChavePath default
legal.page/page/:slug

Central de ajuda

ChavePath default
helpCenter/help
help.categories/help/categories
help.category/help/:slug
help.post/help/:slug

Conteúdo (promoções, blog, notícias, jogo responsável, FAQ)

ChavePath default
promotions/promotions
promotions.category/promotions/:slug
promotions.post/promotions/:slug
blog/blog
blog.category/blog/:slug
blog.post/blog/:slug
news/news
news.category/news/:slug
news.post/news/:slug
responsibleGaming/responsible-gaming
responsibleGaming.category/responsible-gaming/:slug
responsibleGaming.post/responsible-gaming/:slug
faq/faq
faq.category/faq/:slug
faq.post/faq/:slug
faq.game/faq/:provider/:game

:::info Pares categoria/post compartilham o mesmo path help.category e help.post (e os pares equivalentes em promotions, blog, news, responsible-gaming e FAQ) apontam para o mesmo path de um segmento. Um resolver no servidor decide se renderiza listagem de categoria ou detalhe de post conforme a entidade que existe no CMS. Ao renomear, mantenha os dois pares iguais entre si. :::

Outros

ChavePath default
promocode/promocode
profiles/perfis
profiles.detail/perfil/:slug

Regras

Estas regras são verificadas em runtime por validateRoutePaths() (app/utils/routes.ts) e a violação derruba o boot com erro descritivo:

  1. Todo path começa com /.
  2. Rotas dinâmicas precisam manter seus placeholders:slug, :provider, :game, :id, :type, :token não podem ser renomeados nem removidos.
  3. sports.catchAll precisa terminar em /*.

Além disso:

  1. O mapa precisa estar completo — o tipo RoutePathMap exige todas as chaves; um override parcial não compila.
  2. Rotas de API não fazem parte do registryapi/* são endpoints internos do servidor e não são expostos na config de marca.

Usando rotas no código

import { routeHref, gameHref, sportPath } from "~/utils/routes";

// Rota estática
routeHref("casino"); // → "/games" (ou o path da sua marca)

// Rota dinâmica (params tipados por chave)
routeHref("casino.category", { slug: "slots" });

// Link de jogo a partir do slug "provider/game"
gameHref("pgsoft/fortune-tiger");

// Deep link do sportsbook
sportPath("/futebol/brasil");

Nunca escreva paths literais ("/games", "/vip/missions") em componentes — eles quebram assim que a marca renomeia a URL.

Adicionando ou removendo páginas

O Route Registry controla apenas as URLs. Para adicionar ou remover páginas, edite a árvore de rotas em app/router/routes.ts:

  • Rotas devem ficar aninhadas dentro de layout("routes/_layout.tsx", [...]) — é ali que vivem os providers de marca/ambiente.
  • Use index() para a página default de um grupo.
  • Use route(routePattern("chave"), "arquivo.tsx") para páginas nomeadas.
  • Chaves novas precisam entrar em app/types/routes.ts e em app/config/routes/paths.ts (e em todos os overrides de marca, já que o mapa precisa ser completo).
observação

app/router/routes.ts é avaliado em config time, antes dos aliases do Vite existirem — por isso ele usa imports relativos (../types/routes) em vez de ~/.

Fora disso, o fork é seu: crie os componentes, páginas e hooks que precisar.