Navigation
Move between typed embed routes with links, history, params, and prefetching.
Ludicord navigation changes the active embed without reloading the Activity shell. Route types are generated from the app/embeds tree, so invalid static paths can fail in the editor before they reach Discord.
#Link between embeds
Use Link for normal user navigation. It renders an anchor, supports keyboard and browser semantics, and prefetches visible or focused routes by default.
1import { Link } from "ludicord/navigation";23export default function Navbar() {4 return (5 <nav>6 <Link href="home">Home</Link>7 <Link href="me">My profile</Link>8 </nav>9 );10}
Set prefetch={false} for large routes that should load only after a click. Set replace when the current screen should not remain in Activity history.
#Navigate from an event
Use useEmbedRouter() when navigation happens after an action.
1import { useEmbedRouter } from "ludicord/navigation";23export default function embed() {4 const router = useEmbedRouter();5 return <button onClick={() => router.push("game/room-42")}>Join room</button>;6}
#Read the current path
useEmbedPath() returns the normalized active embed path. It is useful for navigation state, analytics, or sending a current-view signal to a realtime route.
1const path = useEmbedPath();23useEffect(() => {4 if (connection.status === "open") connection.emit("view", { path });5}, [connection, connection.status, path]);
#Read dynamic params
Pass the route pattern to useEmbedParams() so generated declarations can infer the parameter names.
1const { roomId } = useEmbedParams("game/:roomId");
Route params are URL input, not authorization. If roomId selects protected server data, the API or WebSocket route must verify that the current session may access it.
#Route groups
Folders wrapped in parentheses organize code but are removed from the public path.
1app/embeds/(games)/chess/embed.tsx → chess2app/embeds/(games)/poker/embed.tsx → poker
Use groups to colocate layouts and boundaries for a section without making internal folder names part of the Activity URL.
#Navigation and Discord
Embed navigation is internal to the Activity. It does not navigate the Discord client or change the Discord channel. Use SDK commands from useDiscordCommands() only when you intentionally need a Discord capability.
#Next step
Open Styling to make the shell and screens adapt to Discord's desktop and mobile surfaces.