# Rotas e navegação > defineOonRoutes e defineOonNavigation — rotas com guards de permissão, lazy loading, layouts por rota, rotas públicas, rotas reservadas e menu por seções. ## Rotas ```tsx title="frontend/src/app/routes.tsx" import { defineOonRoutes } from "@oondemand/oon-core-front/routing"; import { HomePage } from "../pages/HomePage"; import { WorkspaceLayout } from "../layouts/WorkspaceLayout"; export const routes = defineOonRoutes([ { path: "/", component: HomePage }, { path: "/pedidos", lazy: () => import("../pages/PedidosPage"), layout: WorkspaceLayout, permissions: ["pedidos.read"], }, { path: "/relatorios", element: , capabilities: ["core.transactional-email"] }, ]); ``` | Propriedade | Descrição | |---|---| | `path` | Caminho absoluto iniciado por `/` | | `component` | Página React instanciada pelo roteador | | `element` | Elemento já construído | | `lazy` | `() => import("./Pagina")` com export `default` — code splitting | | `layout` | Componente `{ children }` aplicado só a essa rota | | `permissions` | Guard: exige qualquer uma das permissões | | `capabilities` | Guard por capability declarada | | `public` | Rota fora do guard de autenticação e do shell | Cada rota declara **exatamente uma** fonte: `element`, `component` ou `lazy`. Caminhos duplicados são rejeitados. ### Rotas públicas ```tsx { path: "/status", component: StatusPage, public: true } ``` Rotas `public` são renderizadas fora do `ActivationGuard`, do `AppAccessGuard` e do shell autenticado — úteis para páginas de status, landing pages ou portais. Este site é um exemplo: todo ele é composto por rotas públicas de um App Oon. > [!WARNING] > Uma rota pública não deve expor dados privados: o backend continua exigindo autenticação nas APIs. Em Apps `member-central`, a página padrão `/usuarios-acessos` cria um índice privado em `/`; se o seu `/` for público, use `systemPages: { usersAccess: false }` ou mova a página. ### Rotas reservadas Pertencem ao Core e não podem ser declaradas: `/login`, `/accept-invite`, `/first-access`, `/ativacao`, `/instancia-suspensa`, `/instancia-revogada`, `/acesso-negado`. A lista está em `OON_RESERVED_ROUTES`. Para personalizar o login de um portal, use `systemPages: { login: MinhaPaginaDeLogin }` — substitui o conteúdo e mantém rota e guards com o Core. ## Navegação ```ts title="frontend/src/app/navigation.ts" import { defineOonNavigation } from "@oondemand/oon-core-front/routing"; export const navigation = defineOonNavigation([ { label: "Início", href: "/", order: 10 }, { label: "Pedidos", href: "/pedidos", section: "Operação", order: 20, permissions: ["pedidos.read"] }, { label: "Aprovações", href: "/aprovacoes", section: "Operação", order: 30, requires: "temAprovacoes", badge: 3 }, { label: "Documentação", href: "https://exemplo.com/docs", external: true, action: "user-menu" }, ]); ``` | Propriedade | Descrição | |---|---| | `label` | **Obrigatório** | | `href` | Absoluto (`/…`) ou externo com `external: true` | | `section` | Agrupa itens no menu lateral | | `order` | Ordem dentro da seção | | `permissions`, `capabilities` | Esconde o item sem a permissão/capability | | `requires` | Nome de uma condição em `components.menuConditions` | | `children` | Submenu | | `badge`, `icon`, `hidden` | Apresentação | | `action` | `"user-menu"` move o item para o menu do avatar; `"profile"` define "Meu perfil" | Cada item precisa de `href`, `action` ou `children`. ### Condições de visibilidade ```tsx export const app = defineOonApp({ // ... components: { menuConditions: { temAprovacoes: () => useAprovacoesPendentes() > 0, // hook React sem argumentos }, }, }); ``` Quando todos os itens de uma seção dependem de condições falsas, a seção inteira some. Os hooks são chamados sempre na mesma ordem a cada render do menu. ## Comportamento do menu - Seções com `order` respeitado e `aria-current` no item ativo. - No celular, o menu vira gaveta aberta pelo cabeçalho. - Itens `action: "user-menu"` aparecem no menu do avatar — veja abaixo. - Versões ficam no "Sobre" (tooltip do título), fora da tela principal. ## Menu do usuário Itens com `action: "user-menu"` saem do menu lateral e vão para o menu do avatar, entre "Meu perfil" e "Sair". Desde a 0.7.39, eles são **agrupados por `section`**: cada grupo tem título e separador, os grupos seguem a ordem do primeiro item e, dentro de cada grupo, vale `order`. Itens sem `section` formam um grupo sem título. ```ts defineOonNavigation([ { label: "Preferências", href: "/preferencias", section: "Conta", order: 10, action: "user-menu" }, { label: "Usuários e Acessos", href: "/usuarios-acessos", section: "Configurações", order: 60, permissions: ["users.read"], action: "user-menu" }, { label: "Central de ajuda", href: "https://ajuda.exemplo.com", external: true, action: "user-menu" }, ]); ``` ## Reposicionar itens do Core O Core adiciona itens próprios ao menu — **Usuários e Acessos** (`/usuarios-acessos`) e **E-mail transacional** (`/configuracoes/email-transacional`). Desde a 0.7.39, um item de navegação do App com o **mesmo `href`** substitui o item padrão: você escolhe seção, ordem, rótulo ou o menu do usuário, e a rota e a página continuam sendo as do Core. Mantenha as mesmas `permissions` do item original (`users.read`, `transactional-email.config.read`). Fonte: https://sdk.oonapps.com/docs/frontend/rotas-e-navegacao