{ "id": "264b59efe9bb0f4cd34c5cf5", "source": "remix:does", "type": "html", "title": "Route Configuration | Remix", "content": "DocsBlogResourcesReact Router v7 has been released. View the docsDocsBlogResourcesView code on GitHubChat on DiscordReact Router v7 has been released. View the docsRoute ConfigurationGetting StartedQuick Start (5m) Tutorial (30m) Upgrading to v2 Community Future Flags Changelog Discussion TopicsIntroduction, Technical Explanation Runtimes, Adapters, Templates, and Deployment Route Configuration Fullstack Data Flow Server vs. Client Code Execution React Router Progressive Enhancement Pending UI State Management Network Concurrency Management Form vs. fetcher Hot Module Replacement Form Resubmissions File Conventions.client modules .server modules Asset Imports entry.client entry.server root Route File Naming vite.config.ts Route Moduleaction clientAction clientLoader Component ErrorBoundary handle headers HydrateFallback links loader meta shouldRevalidate ComponentsAwait Form Link Links LiveReload Meta NavLink Outlet PrefetchPageLinks Scripts ScrollRestoration HooksuseActionData useAsyncError πŸ†•useAsyncValue πŸ†•useBeforeUnload useBlocker useFetcher useFetchers useFormAction useHref useLoaderData useLocation useMatches useNavigate useNavigation useNavigationType useOutlet useOutletContext useParams unstable_usePrompt useResolvedPath useRevalidator πŸ†•useRouteError πŸ†•useRouteLoaderData useSearchParams useSubmit useViewTransitionState UtilitiesCookies createRemixStub data defer isRouteErrorResponse json unstable_parseMultipartFormData redirect redirectDocument replace Sessions unstable_createFileUploadHandler unstable_createMemoryUploadHandler StylingCSS Bundling Regular CSS CSS Imports CSS in JS CSS Modules PostCSS Tailwind Vanilla Extract Other API@remix-run/dev CLI πŸ†•@remix-run/{adapter} @remix-run/serve create-remix (CLI) @remix-run/node @remix-run/testing GuidesAccessibility Development Strategy API Routes Backend For Frontend Breadcrumbs Guide Browser Support Client Data Module Constraints Contributing CSS Files Data Loading Data Writes Dependency optimization Deployment Disabling JavaScript Environment Variables Error Handling FAQs File Uploads Form Validation Gotchas Index Query Param Lazy Route Discovery Local TLS Manual Dev Server MDX Migrating from React Router Not Found Handling Performance Presets Resource Routes Server Bundles Single Fetch SPA Mode Streaming Templates TypeScript Vite Getting StartedQuick Start (5m) Tutorial (30m) Upgrading to v2 Community Future Flags Changelog Discussion TopicsIntroduction, Technical Explanation Runtimes, Adapters, Templates, and Deployment Route Configuration Fullstack Data Flow Server vs. Client Code Execution React Router Progressive Enhancement Pending UI State Management Network Concurrency Management Form vs. fetcher Hot Module Replacement Form Resubmissions File Conventions.client modules .server modules Asset Imports entry.client entry.server root Route File Naming vite.config.ts Route Moduleaction clientAction clientLoader Component ErrorBoundary handle headers HydrateFallback links loader meta shouldRevalidate ComponentsAwait Form Link Links LiveReload Meta NavLink Outlet PrefetchPageLinks Scripts ScrollRestoration HooksuseActionData useAsyncError πŸ†•useAsyncValue πŸ†•useBeforeUnload useBlocker useFetcher useFetchers useFormAction useHref useLoaderData useLocation useMatches useNavigate useNavigation useNavigationType useOutlet useOutletContext useParams unstable_usePrompt useResolvedPath useRevalidator πŸ†•useRouteError πŸ†•useRouteLoaderData useSearchParams useSubmit useViewTransitionState UtilitiesCookies createRemixStub data defer isRouteErrorResponse json unstable_parseMultipartFormData redirect redirectDocument replace Sessions unstable_createFileUploadHandler unstable_createMemoryUploadHandler StylingCSS Bundling Regular CSS CSS Imports CSS in JS CSS Modules PostCSS Tailwind Vanilla Extract Other API@remix-run/dev CLI πŸ†•@remix-run/{adapter} @remix-run/serve create-remix (CLI) @remix-run/node @remix-run/testing GuidesAccessibility Development Strategy API Routes Backend For Frontend Breadcrumbs Guide Browser Support Client Data Module Constraints Contributing CSS Files Data Loading Data Writes Dependency optimization Deployment Disabling JavaScript Environment Variables Error Handling FAQs File Uploads Form Validation Gotchas Index Query Param Lazy Route Discovery Local TLS Manual Dev Server MDX Migrating from React Router Not Found Handling Performance Presets Resource Routes Server Bundles Single Fetch SPA Mode Streaming Templates TypeScript Vite On this pageModular DesignParallel LoadingConventional Route ConfigurationConventional Route FoldersManual Route ConfigurationOn this pageModular DesignParallel LoadingConventional Route ConfigurationConventional Route FoldersManual Route ConfigurationRoute Configuration One of the foundational concepts in Remix's routing system is the use of nested routes, an approach that traces its roots back to Ember.js. With nested routes, segments of the URL are coupled to both data dependencies and the UI's component hierarchy. A URL like /sales/invoices/102000 not only reveals a clear path in the application but also delineates the relationships and dependencies for different components. Modular Design Nested routes provide clarity by segmenting URLs into multiple parts. Each segment directly correlates with a particular data requirement and component. For instance, in the URL /sales/invoices/102000, each segment - sales, invoices, and 102000 - can be associated with specific data points and UI sections, making it intuitive to manage in the codebase. A feature of nested routing is the ability for several routes in the nested route tree to match a single URL. This granularity ensures that each route is primarily focused on its specific URL segment and related slice of UI. This approach champions the principles of modularity and separation of concerns, ensuring each route remains focused on its core responsibilities. Parallel Loading In some web applications, the sequential loading of data and assets can sometimes lead to an artificially slow user experience. Even when data dependencies aren't interdependent, they may be loaded sequentially because they are coupled to rendering hierarchy, creating an undesirable chain of requests. Remix leverages its nested routing system to optimize load times. When a URL matches multiple routes, Remix will load the required data and assets for all matching routes in parallel. By doing this, Remix effectively sidesteps the conventional pitfall of chained request sequences. This strategy, combined with modern browsers' ability to handle multiple concurrent requests efficiently, positions Remix as a front-runner in delivering highly responsive and swift web applications. It's not just about making your data fetching fast; it's about fetching it in an organized way to provide the best possible experience for the end user. Conventional Route Configuration Remix introduces a key convention to help streamline the routing process: the app/routes folder. When a developer introduces a file within this folder, Remix inherently understands it as a route. This convention simplifies the process of defining routes, associating them with URLs, and rendering the associated components. Here's a sample directory that uses the routes folder convention: app/ β”œβ”€β”€ routes/ β”‚ β”œβ”€β”€ _index.tsx β”‚ β”œβ”€β”€ about.tsx β”‚ β”œβ”€β”€ concerts._index.tsx β”‚ β”œβ”€β”€ concerts.$city.tsx β”‚ β”œβ”€β”€ concerts.trending.tsx β”‚ └── concerts.tsx └── root.tsx All the routes that start with app/routes/concerts. will be child routes of app/routes/concerts.tsx. URL Matched Route Layout / app/routes/_index.tsx app/root.tsx /about app/routes/about.tsx app/root.tsx /concerts app/routes/concerts._index.tsx app/routes/concerts.tsx /concerts/trending app/routes/concerts.trending.tsx app/routes/concerts.tsx /concerts/salt-lake-city app/routes/concerts.$city.tsx app/routes/concerts.tsx Conventional Route Folders For routes that require additional modules or assets, a folder inside of app/routes with a route.tsx file can be used. This method: Co-locates Modules: It gathers all elements connected to a particular route, ensuring logic, styles, and components are closely knit. Simplifies Imports: With related modules in one place, managing imports becomes straightforward, enhancing code maintainability. Facilitates Automatic Code Organization: Using the route.tsx setup inherently promotes a well-organized codebase, beneficial as the application scales. The same routes from above could instead be organized like this: app/ β”œβ”€β”€ routes/ β”‚ β”œβ”€β”€ _index/ β”‚ β”‚ β”œβ”€β”€ signup-form.tsx β”‚ β”‚ └── route.tsx β”‚ β”œβ”€β”€ about/ β”‚ β”‚ β”œβ”€β”€ header.tsx β”‚ β”‚ └── route.tsx β”‚ β”œβ”€β”€ concerts/ β”‚ β”‚ β”œβ”€β”€ favorites-cookie.ts β”‚ β”‚ └── route.tsx β”‚ β”œβ”€β”€ concerts.$city/ β”‚ β”‚ └── route.tsx β”‚ β”œβ”€β”€ concerts._index/ β”‚ β”‚ β”œβ”€β”€ featured.tsx β”‚ β”‚ └── route.tsx β”‚ └── concerts.trending/ β”‚ β”œβ”€β”€ card.tsx β”‚ β”œβ”€β”€ route.tsx β”‚ └── sponsored.tsx └── root.tsx You can read more about the specific patterns in the file names and other features in the Route File Conventions reference. Only the folders directly beneath app/routes will be registered as a route. Deeply nested folders are ignored. The file at app/routes/about/header/route.tsx will not create a route. app/ β”œβ”€β”€ routes/ β”‚ └── about/ β”‚ β”œβ”€β”€ header/ β”‚ β”‚ └── route.tsx β”‚ └── route.tsx └── root.tsx Manual Route Configuration While the app/routes folder offers a convenient convention for developers, Remix appreciates that one size doesn't fit all. There are times when the provided convention might not align with specific project requirements or a developer's preferences. In such cases, Remix allows for manual route configuration via vite.config.ts. This flexibility ensures developers can structure their application in a way that makes sense for their project. If you have not yet migrated to Vite and are still using the Classic Remix Compiler, you can configure routes manually in your remix.config.js file. A common way to structure an app is by top-level features folders. Consider that routes related to a particular theme, like concerts, likely share several modules. Organizing them under a single folder makes sense: app/ β”œβ”€β”€ about/ β”‚ └── route.tsx β”œβ”€β”€ concerts/ β”‚ β”œβ”€β”€ card.tsx β”‚ β”œβ”€β”€ city.tsx β”‚ β”œβ”€β”€ favorites-cookie.ts β”‚ β”œβ”€β”€ home.tsx β”‚ β”œβ”€β”€ layout.tsx β”‚ β”œβ”€β”€ sponsored.tsx β”‚ └── trending.tsx β”œβ”€β”€ home/ β”‚ β”œβ”€β”€ header.tsx β”‚ └── route.tsx └── root.tsx To configure this structure into the same URLs as the previous examples, you can use the routes function in vite.config.ts: import { vitePlugin as remix } from \"@remix-run/dev\"; import { defineConfig } from \"vite\"; export default defineConfig({ plugins: [ remix({ routes(defineRoutes) { return defineRoutes((route) =\u003e { route(\"/\", \"home/route.tsx\", { index: true }); route(\"about\", \"about/route.tsx\"); route(\"concerts\", \"concerts/layout.tsx\", () =\u003e { route(\"\", \"concerts/home.tsx\", { index: true }); route(\"trending\", \"concerts/trending.tsx\"); route(\":city\", \"concerts/city.tsx\"); }); }); }, }), ], }); Remix's route configuration approach blends convention with flexibility. You can use the app/routes folder for an easy, organized way to set up your routes. If you want more control, dislike the file names, or have unique needs, there's vite.config.ts. It is expected that many apps forgo the routes folder convention in favor of vite.config.ts.Β© Shopify, Inc.β€’Docs and examples licensed under MITEdit((storageKey2, restoreKey) =\u003e { if (!window.history.state || !window.history.state.key) { let key = Math.random().toString(32).slice(2); window.history.replaceState({ key }, \"\"); } try { let positions = JSON.parse(sessionStorage.getItem(storageKey2) || \"{}\"); let storedY = positions[restoreKey || window.history.state.key]; if (typeof storedY === \"number\") { window.scrollTo(0, storedY); } } catch (error) { console.error(error); sessionStorage.removeItem(storageKey2); } })(\"react-router-scroll-positions\", null)window.__reactRouterContext = {\"basename\":\"/\",\"future\":{\"unstable_optimizeDeps\":true,\"unstable_subResourceIntegrity\":false,\"v8_middleware\":true,\"v8_splitRouteModules\":true,\"v8_viteEnvironmentApi\":true},\"routeDiscovery\":{\"mode\":\"initial\"},\"ssr\":true,\"isSpaMode\":false};window.__reactRouterContext.stream = new ReadableStream({start(controller){window.__reactRouterContext.streamController = controller;}}).pipeThrough(new TextEncoderStream());import \"/assets/manifest-b010e014.js\"; import * as route0 from \"/assets/root-CtUYAfRS.js\"; import * as route1 from \"/assets/docs-DauuYQK6.js\"; import * as route2 from \"/assets/docs._-B4dRXAHv.js\"; window.__reactRouterRouteModules = {\"root\":route0,\"routes/docs\":route1,\"routes/docs.$\":route2}; import(\"/assets/entry.client-q2ogymM2.js\");window.__reactRouterContext.streamController.enqueue(\"[{\\\"_1\\\":2,\\\"_978\\\":-5,\\\"_979\\\":-5},\\\"loaderData\\\",{\\\"_3\\\":4,\\\"_11\\\":12,\\\"_949\\\":950},\\\"root\\\",{\\\"_5\\\":6,\\\"_7\\\":8,\\\"_9\\\":10},\\\"host\\\",\\\"localhost\\\",\\\"siteUrl\\\",\\\"https://v2.remix.run\\\",\\\"noIndex\\\",false,\\\"routes/docs\\\",{\\\"_13\\\":14},\\\"menu\\\",[15,72,160,214,292,364,527,611,665,707],{\\\"_16\\\":17,\\\"_22\\\":23,\\\"_24\\\":25,\\\"_26\\\":10,\\\"_27\\\":28},\\\"attrs\\\",{\\\"_18\\\":19,\\\"_20\\\":21},\\\"title\\\",\\\"Getting Started\\\",\\\"order\\\",1,\\\"filename\\\",\\\"start/index.md\\\",\\\"slug\\\",\\\"start\\\",\\\"hasContent\\\",\\\"children\\\",[29,36,43,50,59,66],{\\\"_16\\\":30,\\\"_22\\\":32,\\\"_24\\\":33,\\\"_26\\\":34,\\\"_27\\\":35},{\\\"_18\\\":31,\\\"_20\\\":21},\\\"Quick Start (5m)\\\",\\\"start/quickstart.md\\\",\\\"start/quickstart\\\",true,[],{\\\"_16\\\":37,\\\"_22\\\":40,\\\"_24\\\":41,\\\"_26\\\":34,\\\"_27\\\":42},{\\\"_18\\\":38,\\\"_20\\\":39},\\\"Tutorial (30m)\\\",2,\\\"start/tutorial.md\\\",\\\"start/tutorial\\\",[],{\\\"_16\\\":44,\\\"_22\\\":47,\\\"_24\\\":48,\\\"_26\\\":34,\\\"_27\\\":49},{\\\"_18\\\":45,\\\"_20\\\":46},\\\"Upgrading to v2\\\",3,\\\"start/v2.md\\\",\\\"start/v2\\\",[],{\\\"_16\\\":51,\\\"_22\\\":56,\\\"_24\\\":57,\\\"_26\\\":34,\\\"_27\\\":58},{\\\"_18\\\":52,\\\"_53\\\":54,\\\"_20\\\":55},\\\"Community\\\",\\\"description\\\",\\\"Community resources for learning Remix and related technologies\\\",4,\\\"start/community.md\\\",\\\"start/community\\\",[],{\\\"_16\\\":60,\\\"_22\\\":63,\\\"_24\\\":64,\\\"_26\\\":34,\\\"_27\\\":65},{\\\"_18\\\":61,\\\"_20\\\":62},\\\"Future Flags\\\",5,\\\"start/future-flags.md\\\",\\\"start/future-flags\\\",[],{\\\"_16\\\":67,\\\"_22\\\":69,\\\"_24\\\":70,\\\"_26\\\":34,\\\"_27\\\":71},{\\\"_18\\\":68},\\\"Changelog\\\",\\\"start/changelog.md\\\",\\\"start/changelog\\\",[],{\\\"_16\\\":73,\\\"_22\\\":75,\\\"_24\\\":76,\\\"_26\\\":10,\\\"_27\\\":77},{\\\"_18\\\":74,\\\"_20\\\":39},\\\"Discussion Topics\\\",\\\"discussion/index.md\\\",\\\"discussion\\\",[78,84,90,96,102,108,115,122,129,136,142,148,154],{\\\"_16\\\":79,\\\"_22\\\":81,\\\"_24\\\":82,\\\"_26\\\":34,\\\"_27\\\":83},{\\\"_18\\\":80,\\\"_20\\\":21},\\\"Introduction, Technical Explanation\\\",\\\"discussion/introduction.md\\\",\\\"discussion/introduction\\\",[],{\\\"_16\\\":85,\\\"_22\\\":87,\\\"_24\\\":88,\\\"_26\\\":34,\\\"_27\\\":89},{\\\"_18\\\":86,\\\"_20\\\":39},\\\"Runtimes, Adapters, Templates, and Deployment\\\",\\\"discussion/runtimes.md\\\",\\\"discussion/runtimes\\\",[],{\\\"_16\\\":91,\\\"_22\\\":93,\\\"_24\\\":94,\\\"_26\\\":34,\\\"_27\\\":95},{\\\"_18\\\":92,\\\"_20\\\":46},\\\"Route Configuration\\\",\\\"discussion/routes.md\\\",\\\"discussion/routes\\\",[],{\\\"_16\\\":97,\\\"_22\\\":99,\\\"_24\\\":100,\\\"_26\\\":34,\\\"_27\\\":101},{\\\"_18\\\":98,\\\"_20\\\":55},\\\"Fullstack Data Flow\\\",\\\"discussion/data-flow.md\\\",\\\"discussion/data-flow\\\",[],{\\\"_16\\\":103,\\\"_22\\\":105,\\\"_24\\\":106,\\\"_26\\\":34,\\\"_27\\\":107},{\\\"_18\\\":104,\\\"_20\\\":62},\\\"Server vs. Client Code Execution\\\",\\\"discussion/server-vs-client.md\\\",\\\"discussion/server-vs-client\\\",[],{\\\"_16\\\":109,\\\"_22\\\":112,\\\"_24\\\":113,\\\"_26\\\":34,\\\"_27\\\":114},{\\\"_18\\\":110,\\\"_20\\\":111},\\\"React Router\\\",6,\\\"discussion/react-router.md\\\",\\\"discussion/react-router\\\",[],{\\\"_16\\\":116,\\\"_22\\\":119,\\\"_24\\\":120,\\\"_26\\\":34,\\\"_27\\\":121},{\\\"_18\\\":117,\\\"_20\\\":118},\\\"Progressive Enhancement\\\",7,\\\"discussion/progressive-enhancement.md\\\",\\\"discussion/progressive-enhancement\\\",[],{\\\"_16\\\":123,\\\"_22\\\":126,\\\"_24\\\":127,\\\"_26\\\":34,\\\"_27\\\":128},{\\\"_18\\\":124,\\\"_20\\\":125},\\\"Pending UI\\\",8,\\\"discussion/pending-ui.md\\\",\\\"discussion/pending-ui\\\",[],{\\\"_16\\\":130,\\\"_22\\\":133,\\\"_24\\\":134,\\\"_26\\\":34,\\\"_27\\\":135},{\\\"_18\\\":131,\\\"_20\\\":132},\\\"State Management\\\",9,\\\"discussion/state-management.md\\\",\\\"discussion/state-management\\\",[],{\\\"_16\\\":137,\\\"_22\\\":139,\\\"_24\\\":140,\\\"_26\\\":34,\\\"_27\\\":141},{\\\"_18\\\":138},\\\"Network Concurrency Management\\\",\\\"discussion/concurrency.md\\\",\\\"discussion/concurrency\\\",[],{\\\"_16\\\":143,\\\"_22\\\":145,\\\"_24\\\":146,\\\"_26\\\":34,\\\"_27\\\":147},{\\\"_18\\\":144},\\\"Form vs. fetcher\\\",\\\"discussion/form-vs-fetcher.md\\\",\\\"discussion/form-vs-fetcher\\\",[],{\\\"_16\\\":149,\\\"_22\\\":151,\\\"_24\\\":152,\\\"_26\\\":34,\\\"_27\\\":153},{\\\"_18\\\":150},\\\"Hot Module Replacement\\\",\\\"discussion/hot-module-replacement.md\\\",\\\"discussion/hot-module-replacement\\\",[],{\\\"_16\\\":155,\\\"_22\\\":157,\\\"_24\\\":158,\\\"_26\\\":34,\\\"_27\\\":159},{\\\"_18\\\":156},\\\"Form Resubmissions\\\",\\\"discussion/resubmissions.md\\\",\\\"discussion/resubmissions\\\",[],{\\\"_16\\\":161,\\\"_22\\\":163,\\\"_24\\\":164,\\\"_26\\\":10,\\\"_27\\\":165},{\\\"_18\\\":162,\\\"_20\\\":46},\\\"File Conventions\\\",\\\"file-conventions/index.md\\\",\\\"file-conventions\\\",[166,173,179,185,191,197,202,208],{\\\"_16\\\":167,\\\"_22\\\":170,\\\"_24\\\":171,\\\"_26\\\":34,\\\"_27\\\":172},{\\\"_18\\\":168,\\\"_169\\\":10},\\\".client modules\\\",\\\"toc\\\",\\\"file-conventions/-client.md\\\",\\\"file-conventions/-client\\\",[],{\\\"_16\\\":174,\\\"_22\\\":176,\\\"_24\\\":177,\\\"_26\\\":34,\\\"_27\\\":178},{\\\"_18\\\":175,\\\"_169\\\":10},\\\".server modules\\\",\\\"file-conventions/-server.md\\\",\\\"file-conventions/-server\\\",[],{\\\"_16\\\":180,\\\"_22\\\":182,\\\"_24\\\":183,\\\"_26\\\":34,\\\"_27\\\":184},{\\\"_18\\\":181,\\\"_169\\\":10},\\\"Asset Imports\\\",\\\"file-conventions/asset-imports.md\\\",\\\"file-conventions/asset-imports\\\",[],{\\\"_16\\\":186,\\\"_22\\\":188,\\\"_24\\\":189,\\\"_26\\\":34,\\\"_27\\\":190},{\\\"_18\\\":187,\\\"_169\\\":10},\\\"entry.client\\\",\\\"file-conventions/entry.client.md\\\",\\\"file-conventions/entry.client\\\",[],{\\\"_16\\\":192,\\\"_22\\\":194,\\\"_24\\\":195,\\\"_26\\\":34,\\\"_27\\\":196},{\\\"_18\\\":193,\\\"_169\\\":10},\\\"entry.server\\\",\\\"file-conventions/entry.server.md\\\",\\\"file-conventions/entry.server\\\",[],{\\\"_16\\\":198,\\\"_22\\\":199,\\\"_24\\\":200,\\\"_26\\\":34,\\\"_27\\\":201},{\\\"_18\\\":3,\\\"_169\\\":10},\\\"file-conventions/root.md\\\",\\\"file-conventions/root\\\",[],{\\\"_16\\\":203,\\\"_22\\\":205,\\\"_24\\\":206,\\\"_26\\\":34,\\\"_27\\\":207},{\\\"_18\\\":204},\\\"Route File Naming\\\",\\\"file-conventions/routes.md\\\",\\\"file-conventions/routes\\\",[],{\\\"_16\\\":209,\\\"_22\\\":211,\\\"_24\\\":212,\\\"_26\\\":34,\\\"_27\\\":213},{\\\"_18\\\":210},\\\"vite.config.ts\\\",\\\"file-conventions/vite-config.md\\\",\\\"file-conventions/vite-config\\\",[],{\\\"_16\\\":215,\\\"_22\\\":217,\\\"_24\\\":218,\\\"_26\\\":10,\\\"_27\\\":219},{\\\"_18\\\":216,\\\"_20\\\":55},\\\"Route Module\\\",\\\"route/index.md\\\",\\\"route\\\",[220,226,232,238,244,250,256,262,268,274,280,286],{\\\"_16\\\":221,\\\"_22\\\":223,\\\"_24\\\":224,\\\"_26\\\":34,\\\"_27\\\":225},{\\\"_18\\\":222},\\\"action\\\",\\\"route/action.md\\\",\\\"route/action\\\",[],{\\\"_16\\\":227,\\\"_22\\\":229,\\\"_24\\\":230,\\\"_26\\\":34,\\\"_27\\\":231},{\\\"_18\\\":228},\\\"clientAction\\\",\\\"route/client-action.md\\\",\\\"route/client-action\\\",[],{\\\"_16\\\":233,\\\"_22\\\":235,\\\"_24\\\":236,\\\"_26\\\":34,\\\"_27\\\":237},{\\\"_18\\\":234},\\\"clientLoader\\\",\\\"route/client-loader.md\\\",\\\"route/client-loader\\\",[],{\\\"_16\\\":239,\\\"_22\\\":241,\\\"_24\\\":242,\\\"_26\\\":34,\\\"_27\\\":243},{\\\"_18\\\":240},\\\"Component\\\",\\\"route/component.md\\\",\\\"route/component\\\",[],{\\\"_16\\\":245,\\\"_22\\\":247,\\\"_24\\\":248,\\\"_26\\\":34,\\\"_27\\\":249},{\\\"_18\\\":246},\\\"ErrorBoundary\\\",\\\"route/error-boundary.md\\\",\\\"route/error-boundary\\\",[],{\\\"_16\\\":251,\\\"_22\\\":253,\\\"_24\\\":254,\\\"_26\\\":34,\\\"_27\\\":255},{\\\"_18\\\":252},\\\"handle\\\",\\\"route/handle.md\\\",\\\"route/handle\\\",[],{\\\"_16\\\":257,\\\"_22\\\":259,\\\"_24\\\":260,\\\"_26\\\":34,\\\"_27\\\":261},{\\\"_18\\\":258},\\\"headers\\\",\\\"route/headers.md\\\",\\\"route/headers\\\",[],{\\\"_16\\\":263,\\\"_22\\\":265,\\\"_24\\\":266,\\\"_26\\\":34,\\\"_27\\\":267},{\\\"_18\\\":264},\\\"HydrateFallback\\\",\\\"route/hydrate-fallback.md\\\",\\\"route/hydrate-fallback\\\",[],{\\\"_16\\\":269,\\\"_22\\\":271,\\\"_24\\\":272,\\\"_26\\\":34,\\\"_27\\\":273},{\\\"_18\\\":270},\\\"links\\\",\\\"route/links.md\\\",\\\"route/links\\\",[],{\\\"_16\\\":275,\\\"_22\\\":277,\\\"_24\\\":278,\\\"_26\\\":34,\\\"_27\\\":279},{\\\"_18\\\":276},\\\"loader\\\",\\\"route/loader.md\\\",\\\"route/loader\\\",[],{\\\"_16\\\":281,\\\"_22\\\":283,\\\"_24\\\":284,\\\"_26\\\":34,\\\"_27\\\":285},{\\\"_18\\\":282},\\\"meta\\\",\\\"route/meta.md\\\",\\\"route/meta\\\",[],{\\\"_16\\\":287,\\\"_22\\\":289,\\\"_24\\\":290,\\\"_26\\\":34,\\\"_27\\\":291},{\\\"_18\\\":288},\\\"shouldRevalidate\\\",\\\"route/should-revalidate.md\\\",\\\"route/should-revalidate\\\",[],{\\\"_16\\\":293,\\\"_22\\\":295,\\\"_24\\\":296,\\\"_26\\\":10,\\\"_27\\\":297},{\\\"_18\\\":294,\\\"_20\\\":62},\\\"Components\\\",\\\"components/index.md\\\",\\\"components\\\",[298,304,310,316,322,328,334,340,346,352,358],{\\\"_16\\\":299,\\\"_22\\\":301,\\\"_24\\\":302,\\\"_26\\\":34,\\\"_27\\\":303},{\\\"_18\\\":300},\\\"Await\\\",\\\"components/await.md\\\",\\\"components/await\\\",[],{\\\"_16\\\":305,\\\"_22\\\":307,\\\"_24\\\":308,\\\"_26\\\":34,\\\"_27\\\":309},{\\\"_18\\\":306},\\\"Form\\\",\\\"components/form.md\\\",\\\"components/form\\\",[],{\\\"_16\\\":311,\\\"_22\\\":313,\\\"_24\\\":314,\\\"_26\\\":34,\\\"_27\\\":315},{\\\"_18\\\":312},\\\"Link\\\",\\\"components/link.md\\\",\\\"components/link\\\",[],{\\\"_16\\\":317,\\\"_22\\\":319,\\\"_24\\\":320,\\\"_26\\\":34,\\\"_27\\\":321},{\\\"_18\\\":318,\\\"_169\\\":10},\\\"Links\\\",\\\"components/links.md\\\",\\\"components/links\\\",[],{\\\"_16\\\":323,\\\"_22\\\":325,\\\"_24\\\":326,\\\"_26\\\":34,\\\"_27\\\":327},{\\\"_18\\\":324,\\\"_169\\\":10},\\\"LiveReload\\\",\\\"components/live-reload.md\\\",\\\"components/live-reload\\\",[],{\\\"_16\\\":329,\\\"_22\\\":331,\\\"_24\\\":332,\\\"_26\\\":34,\\\"_27\\\":333},{\\\"_18\\\":330,\\\"_169\\\":10},\\\"Meta\\\",\\\"components/meta.md\\\",\\\"components/meta\\\",[],{\\\"_16\\\":335,\\\"_22\\\":337,\\\"_24\\\":338,\\\"_26\\\":34,\\\"_27\\\":339},{\\\"_18\\\":336},\\\"NavLink\\\",\\\"components/nav-link.md\\\",\\\"components/nav-link\\\",[],{\\\"_16\\\":341,\\\"_22\\\":343,\\\"_24\\\":344,\\\"_26\\\":34,\\\"_27\\\":345},{\\\"_18\\\":342},\\\"Outlet\\\",\\\"components/outlet.md\\\",\\\"components/outlet\\\",[],{\\\"_16\\\":347,\\\"_22\\\":349,\\\"_24\\\":350,\\\"_26\\\":34,\\\"_27\\\":351},{\\\"_18\\\":348,\\\"_169\\\":10},\\\"PrefetchPageLinks\\\",\\\"components/prefetch-page-links.md\\\",\\\"components/prefetch-page-links\\\",[],{\\\"_16\\\":353,\\\"_22\\\":355,\\\"_24\\\":356,\\\"_26\\\":34,\\\"_27\\\":357},{\\\"_18\\\":354,\\\"_169\\\":10},\\\"Scripts\\\",\\\"components/scripts.md\\\",\\\"components/scripts\\\",[],{\\\"_16\\\":359,\\\"_22\\\":361,\\\"_24\\\":362,\\\"_26\\\":34,\\\"_27\\\":363},{\\\"_18\\\":360},\\\"ScrollRestoration\\\",\\\"components/scroll-restoration.md\\\",\\\"components/scroll-restoration\\\",[],{\\\"_16\\\":365,\\\"_22\\\":367,\\\"_24\\\":368,\\\"_26\\\":10,\\\"_27\\\":369},{\\\"_18\\\":366,\\\"_20\\\":111},\\\"Hooks\\\",\\\"hooks/index.md\\\",\\\"hooks\\\",[370,376,383,389,395,401,407,413,419,425,431,437,443,449,455,461,467,473,479,485,491,497,503,509,515,521],{\\\"_16\\\":371,\\\"_22\\\":373,\\\"_24\\\":374,\\\"_26\\\":34,\\\"_27\\\":375},{\\\"_18\\\":372,\\\"_169\\\":10},\\\"useActionData\\\",\\\"hooks/use-action-data.md\\\",\\\"hooks/use-action-data\\\",[],{\\\"_16\\\":377,\\\"_22\\\":380,\\\"_24\\\":381,\\\"_26\\\":34,\\\"_27\\\":382},{\\\"_18\\\":378,\\\"_379\\\":34},\\\"useAsyncError\\\",\\\"new\\\",\\\"hooks/use-async-error.md\\\",\\\"hooks/use-async-error\\\",[],{\\\"_16\\\":384,\\\"_22\\\":386,\\\"_24\\\":387,\\\"_26\\\":34,\\\"_27\\\":388},{\\\"_18\\\":385,\\\"_379\\\":34},\\\"useAsyncValue\\\",\\\"hooks/use-async-value.md\\\",\\\"hooks/use-async-value\\\",[],{\\\"_16\\\":390,\\\"_22\\\":392,\\\"_24\\\":393,\\\"_26\\\":34,\\\"_27\\\":394},{\\\"_18\\\":391,\\\"_169\\\":10},\\\"useBeforeUnload\\\",\\\"hooks/use-before-unload.md\\\",\\\"hooks/use-before-unload\\\",[],{\\\"_16\\\":396,\\\"_22\\\":398,\\\"_24\\\":399,\\\"_26\\\":34,\\\"_27\\\":400},{\\\"_18\\\":397},\\\"useBlocker\\\",\\\"hooks/use-blocker.md\\\",\\\"hooks/use-blocker\\\",[],{\\\"_16\\\":402,\\\"_22\\\":404,\\\"_24\\\":405,\\\"_26\\\":34,\\\"_27\\\":406},{\\\"_18\\\":403},\\\"useFetcher\\\",\\\"hooks/use-fetcher.md\\\",\\\"hooks/use-fetcher\\\",[],{\\\"_16\\\":408,\\\"_22\\\":410,\\\"_24\\\":411,\\\"_26\\\":34,\\\"_27\\\":412},{\\\"_18\\\":409,\\\"_169\\\":10},\\\"useFetchers\\\",\\\"hooks/use-fetchers.md\\\",\\\"hooks/use-fetchers\\\",[],{\\\"_16\\\":414,\\\"_22\\\":416,\\\"_24\\\":417,\\\"_26\\\":34,\\\"_27\\\":418},{\\\"_18\\\":415},\\\"useFormAction\\\",\\\"hooks/use-form-action.md\\\",\\\"hooks/use-form-action\\\",[],{\\\"_16\\\":420,\\\"_22\\\":422,\\\"_24\\\":423,\\\"_26\\\":34,\\\"_27\\\":424},{\\\"_18\\\":421},\\\"useHref\\\",\\\"hooks/use-href.md\\\",\\\"hooks/use-href\\\",[],{\\\"_16\\\":426,\\\"_22\\\":428,\\\"_24\\\":429,\\\"_26\\\":34,\\\"_27\\\":430},{\\\"_18\\\":427},\\\"useLoaderData\\\",\\\"hooks/use-loader-data.md\\\",\\\"hooks/use-loader-data\\\",[],{\\\"_16\\\":432,\\\"_22\\\":434,\\\"_24\\\":435,\\\"_26\\\":34,\\\"_27\\\":436},{\\\"_18\\\":433},\\\"useLocation\\\",\\\"hooks/use-location.md\\\",\\\"hooks/use-location\\\",[],{\\\"_16\\\":438,\\\"_22\\\":440,\\\"_24\\\":441,\\\"_26\\\":34,\\\"_27\\\":442},{\\\"_18\\\":439,\\\"_169\\\":10},\\\"useMatches\\\",\\\"hooks/use-matches.md\\\",\\\"hooks/use-matches\\\",[],{\\\"_16\\\":444,\\\"_22\\\":446,\\\"_24\\\":447,\\\"_26\\\":34,\\\"_27\\\":448},{\\\"_18\\\":445},\\\"useNavigate\\\",\\\"hooks/use-navigate.md\\\",\\\"hooks/use-navigate\\\",[],{\\\"_16\\\":450,\\\"_22\\\":452,\\\"_24\\\":453,\\\"_26\\\":34,\\\"_27\\\":454},{\\\"_18\\\":451},\\\"useNavigation\\\",\\\"hooks/use-navigation.md\\\",\\\"hooks/use-navigation\\\",[],{\\\"_16\\\":456,\\\"_22\\\":458,\\\"_24\\\":459,\\\"_26\\\":34,\\\"_27\\\":460},{\\\"_18\\\":457},\\\"useNavigationType\\\",\\\"hooks/use-navigation-type.md\\\",\\\"hooks/use-navigation-type\\\",[],{\\\"_16\\\":462,\\\"_22\\\":464,\\\"_24\\\":465,\\\"_26\\\":34,\\\"_27\\\":466},{\\\"_18\\\":463},\\\"useOutlet\\\",\\\"hooks/use-outlet.md\\\",\\\"hooks/use-outlet\\\",[],{\\\"_16\\\":468,\\\"_22\\\":470,\\\"_24\\\":471,\\\"_26\\\":34,\\\"_27\\\":472},{\\\"_18\\\":469},\\\"useOutletContext\\\",\\\"hooks/use-outlet-context.md\\\",\\\"hooks/use-outlet-context\\\",[],{\\\"_16\\\":474,\\\"_22\\\":476,\\\"_24\\\":477,\\\"_26\\\":34,\\\"_27\\\":478},{\\\"_18\\\":475},\\\"useParams\\\",\\\"hooks/use-params.md\\\",\\\"hooks/use-params\\\",[],{\\\"_16\\\":480,\\\"_22\\\":482,\\\"_24\\\":483,\\\"_26\\\":34,\\\"_27\\\":484},{\\\"_18\\\":481},\\\"unstable_usePrompt\\\",\\\"hooks/use-prompt.md\\\",\\\"hooks/use-prompt\\\",[],{\\\"_16\\\":486,\\\"_22\\\":488,\\\"_24\\\":489,\\\"_26\\\":34,\\\"_27\\\":490},{\\\"_18\\\":487},\\\"useResolvedPath\\\",\\\"hooks/use-resolved-path.md\\\",\\\"hooks/use-resolved-path\\\",[],{\\\"_16\\\":492,\\\"_22\\\":494,\\\"_24\\\":495,\\\"_26\\\":34,\\\"_27\\\":496},{\\\"_18\\\":493,\\\"_379\\\":34},\\\"useRevalidator\\\",\\\"hooks/use-revalidator.md\\\",\\\"hooks/use-revalidator\\\",[],{\\\"_16\\\":498,\\\"_22\\\":500,\\\"_24\\\":501,\\\"_26\\\":34,\\\"_27\\\":502},{\\\"_18\\\":499,\\\"_379\\\":34},\\\"useRouteError\\\",\\\"hooks/use-route-error.md\\\",\\\"hooks/use-route-error\\\",[],{\\\"_16\\\":504,\\\"_22\\\":506,\\\"_24\\\":507,\\\"_26\\\":34,\\\"_27\\\":508},{\\\"_18\\\":505,\\\"_169\\\":10},\\\"useRouteLoaderData\\\",\\\"hooks/use-route-loader-data.md\\\",\\\"hooks/use-route-loader-data\\\",[],{\\\"_16\\\":510,\\\"_22\\\":512,\\\"_24\\\":513,\\\"_26\\\":34,\\\"_27\\\":514},{\\\"_18\\\":511},\\\"useSearchParams\\\",\\\"hooks/use-search-params.md\\\",\\\"hooks/use-search-params\\\",[],{\\\"_16\\\":516,\\\"_22\\\":518,\\\"_24\\\":519,\\\"_26\\\":34,\\\"_27\\\":520},{\\\"_18\\\":517},\\\"useSubmit\\\",\\\"hooks/use-submit.md\\\",\\\"hooks/use-submit\\\",[],{\\\"_16\\\":522,\\\"_22\\\":524,\\\"_24\\\":525,\\\"_26\\\":34,\\\"_27\\\":526},{\\\"_18\\\":523,\\\"_169\\\":10},\\\"useViewTransitionState\\\",\\\"hooks/use-view-transition-state.md\\\",\\\"hooks/use-view-transition-state\\\",[],{\\\"_16\\\":528,\\\"_22\\\":530,\\\"_24\\\":531,\\\"_26\\\":10,\\\"_27\\\":532},{\\\"_18\\\":529,\\\"_20\\\":111},\\\"Utilities\\\",\\\"utils/index.md\\\",\\\"utils\\\",[533,539,545,551,557,563,569,575,581,587,593,599,605],{\\\"_16\\\":534,\\\"_22\\\":536,\\\"_24\\\":537,\\\"_26\\\":34,\\\"_27\\\":538},{\\\"_18\\\":535},\\\"Cookies\\\",\\\"utils/cookies.md\\\",\\\"utils/cookies\\\",[],{\\\"_16\\\":540,\\\"_22\\\":542,\\\"_24\\\":543,\\\"_26\\\":34,\\\"_27\\\":544},{\\\"_18\\\":541},\\\"createRemixStub\\\",\\\"utils/create-remix-stub.md\\\",\\\"utils/create-remix-stub\\\",[],{\\\"_16\\\":546,\\\"_22\\\":548,\\\"_24\\\":549,\\\"_26\\\":34,\\\"_27\\\":550},{\\\"_18\\\":547,\\\"_169\\\":10},\\\"data\\\",\\\"utils/data.md\\\",\\\"utils/data\\\",[],{\\\"_16\\\":552,\\\"_22\\\":554,\\\"_24\\\":555,\\\"_26\\\":34,\\\"_27\\\":556},{\\\"_18\\\":553,\\\"_169\\\":10},\\\"defer\\\",\\\"utils/defer.md\\\",\\\"utils/defer\\\",[],{\\\"_16\\\":558,\\\"_22\\\":560,\\\"_24\\\":561,\\\"_26\\\":34,\\\"_27\\\":562},{\\\"_18\\\":559,\\\"_169\\\":10},\\\"isRouteErrorResponse\\\",\\\"utils/is-route-error-response.md\\\",\\\"utils/is-route-error-response\\\",[],{\\\"_16\\\":564,\\\"_22\\\":566,\\\"_24\\\":567,\\\"_26\\\":34,\\\"_27\\\":568},{\\\"_18\\\":565,\\\"_169\\\":10},\\\"json\\\",\\\"utils/json.md\\\",\\\"utils/json\\\",[],{\\\"_16\\\":570,\\\"_22\\\":572,\\\"_24\\\":573,\\\"_26\\\":34,\\\"_27\\\":574},{\\\"_18\\\":571},\\\"unstable_parseMultipartFormData\\\",\\\"utils/parse-multipart-form-data.md\\\",\\\"utils/parse-multipart-form-data\\\",[],{\\\"_16\\\":576,\\\"_22\\\":578,\\\"_24\\\":579,\\\"_26\\\":34,\\\"_27\\\":580},{\\\"_18\\\":577,\\\"_169\\\":10},\\\"redirect\\\",\\\"utils/redirect.md\\\",\\\"utils/redirect\\\",[],{\\\"_16\\\":582,\\\"_22\\\":584,\\\"_24\\\":585,\\\"_26\\\":34,\\\"_27\\\":586},{\\\"_18\\\":583,\\\"_169\\\":10},\\\"redirectDocument\\\",\\\"utils/redirectDocument.md\\\",\\\"utils/redirectDocument\\\",[],{\\\"_16\\\":588,\\\"_22\\\":590,\\\"_24\\\":591,\\\"_26\\\":34,\\\"_27\\\":592},{\\\"_18\\\":589,\\\"_169\\\":10},\\\"replace\\\",\\\"utils/replace.md\\\",\\\"utils/replace\\\",[],{\\\"_16\\\":594,\\\"_22\\\":596,\\\"_24\\\":597,\\\"_26\\\":34,\\\"_27\\\":598},{\\\"_18\\\":595},\\\"Sessions\\\",\\\"utils/sessions.md\\\",\\\"utils/sessions\\\",[],{\\\"_16\\\":600,\\\"_22\\\":602,\\\"_24\\\":603,\\\"_26\\\":34,\\\"_27\\\":604},{\\\"_18\\\":601,\\\"_169\\\":10},\\\"unstable_createFileUploadHandler\\\",\\\"utils/unstable-create-file-upload-handler.md\\\",\\\"utils/unstable-create-file-upload-handler\\\",[],{\\\"_16\\\":606,\\\"_22\\\":608,\\\"_24\\\":609,\\\"_26\\\":34,\\\"_27\\\":610},{\\\"_18\\\":607,\\\"_169\\\":10},\\\"unstable_createMemoryUploadHandler\\\",\\\"utils/unstable-create-memory-upload-handler.md\\\",\\\"utils/unstable-create-memory-upload-handler\\\",[],{\\\"_16\\\":612,\\\"_22\\\":614,\\\"_24\\\":615,\\\"_26\\\":10,\\\"_27\\\":616},{\\\"_18\\\":613,\\\"_20\\\":118},\\\"Styling\\\",\\\"styling/index.md\\\",\\\"styling\\\",[617,623,629,635,641,647,653,659],{\\\"_16\\\":618,\\\"_22\\\":620,\\\"_24\\\":621,\\\"_26\\\":34,\\\"_27\\\":622},{\\\"_18\\\":619},\\\"CSS Bundling\\\",\\\"styling/bundling.md\\\",\\\"styling/bundling\\\",[],{\\\"_16\\\":624,\\\"_22\\\":626,\\\"_24\\\":627,\\\"_26\\\":34,\\\"_27\\\":628},{\\\"_18\\\":625},\\\"Regular CSS\\\",\\\"styling/css.md\\\",\\\"styling/css\\\",[],{\\\"_16\\\":630,\\\"_22\\\":632,\\\"_24\\\":633,\\\"_26\\\":34,\\\"_27\\\":634},{\\\"_18\\\":631},\\\"CSS Imports\\\",\\\"styling/css-imports.md\\\",\\\"styling/css-imports\\\",[],{\\\"_16\\\":636,\\\"_22\\\":638,\\\"_24\\\":639,\\\"_26\\\":34,\\\"_27\\\":640},{\\\"_18\\\":637},\\\"CSS in JS\\\",\\\"styling/css-in-js.md\\\",\\\"styling/css-in-js\\\",[],{\\\"_16\\\":642,\\\"_22\\\":644,\\\"_24\\\":645,\\\"_26\\\":34,\\\"_27\\\":646},{\\\"_18\\\":643},\\\"CSS Modules\\\",\\\"styling/css-modules.md\\\",\\\"styling/css-modules\\\",[],{\\\"_16\\\":648,\\\"_22\\\":650,\\\"_24\\\":651,\\\"_26\\\":34,\\\"_27\\\":652},{\\\"_18\\\":649},\\\"PostCSS\\\",\\\"styling/postcss.md\\\",\\\"styling/postcss\\\",[],{\\\"_16\\\":654,\\\"_22\\\":656,\\\"_24\\\":657,\\\"_26\\\":34,\\\"_27\\\":658},{\\\"_18\\\":655},\\\"Tailwind\\\",\\\"styling/tailwind.md\\\",\\\"styling/tailwind\\\",[],{\\\"_16\\\":660,\\\"_22\\\":662,\\\"_24\\\":663,\\\"_26\\\":34,\\\"_27\\\":664},{\\\"_18\\\":661},\\\"Vanilla Extract\\\",\\\"styling/vanilla-extract.md\\\",\\\"styling/vanilla-extract\\\",[],{\\\"_16\\\":666,\\\"_22\\\":668,\\\"_24\\\":669,\\\"_26\\\":10,\\\"_27\\\":670},{\\\"_18\\\":667,\\\"_20\\\":132},\\\"Other API\\\",\\\"other-api/index.md\\\",\\\"other-api\\\",[671,677,683,689,695,701],{\\\"_16\\\":672,\\\"_22\\\":674,\\\"_24\\\":675,\\\"_26\\\":34,\\\"_27\\\":676},{\\\"_18\\\":673,\\\"_20\\\":39,\\\"_379\\\":34},\\\"@remix-run/dev CLI\\\",\\\"other-api/dev.md\\\",\\\"other-api/dev\\\",[],{\\\"_16\\\":678,\\\"_22\\\":680,\\\"_24\\\":681,\\\"_26\\\":34,\\\"_27\\\":682},{\\\"_18\\\":679,\\\"_20\\\":46},\\\"@remix-run/{adapter}\\\",\\\"other-api/adapter.md\\\",\\\"other-api/adapter\\\",[],{\\\"_16\\\":684,\\\"_22\\\":686,\\\"_24\\\":687,\\\"_26\\\":34,\\\"_27\\\":688},{\\\"_18\\\":685,\\\"_20\\\":46},\\\"@remix-run/serve\\\",\\\"other-api/serve.md\\\",\\\"other-api/serve\\\",[],{\\\"_16\\\":690,\\\"_22\\\":692,\\\"_24\\\":693,\\\"_26\\\":34,\\\"_27\\\":694},{\\\"_18\\\":691},\\\"create-remix (CLI)\\\",\\\"other-api/create-remix.md\\\",\\\"other-api/create-remix\\\",[],{\\\"_16\\\":696,\\\"_22\\\":698,\\\"_24\\\":699,\\\"_26\\\":34,\\\"_27\\\":700},{\\\"_18\\\":697},\\\"@remix-run/node\\\",\\\"other-api/node.md\\\",\\\"other-api/node\\\",[],{\\\"_16\\\":702,\\\"_22\\\":704,\\\"_24\\\":705,\\\"_26\\\":34,\\\"_27\\\":706},{\\\"_18\\\":703},\\\"@remix-run/testing\\\",\\\"other-api/testing.md\\\",\\\"other-api/testing\\\",[],{\\\"_16\\\":708,\\\"_22\\\":711,\\\"_24\\\":712,\\\"_26\\\":10,\\\"_27\\\":713},{\\\"_18\\\":709,\\\"_20\\\":710},\\\"Guides\\\",10,\\\"guides/index.md\\\",\\\"guides\\\",[714,720,726,732,738,744,750,756,762,769,775,782,788,794,800,806,812,818,825,831,837,843,849,855,861,867,874,881,887,893,899,905,911,917,923,930,937,943],{\\\"_16\\\":715,\\\"_22\\\":717,\\\"_24\\\":718,\\\"_26\\\":34,\\\"_27\\\":719},{\\\"_18\\\":716},\\\"Accessibility\\\",\\\"guides/accessibility.md\\\",\\\"guides/accessibility\\\",[],{\\\"_16\\\":721,\\\"_22\\\":723,\\\"_24\\\":724,\\\"_26\\\":34,\\\"_27\\\":725},{\\\"_18\\\":722},\\\"Development Strategy\\\",\\\"guides/api-development-strategy.md\\\",\\\"guides/api-development-strategy\\\",[],{\\\"_16\\\":727,\\\"_22\\\":729,\\\"_24\\\":730,\\\"_26\\\":34,\\\"_27\\\":731},{\\\"_18\\\":728},\\\"API Routes\\\",\\\"guides/api-routes.md\\\",\\\"guides/api-routes\\\",[],{\\\"_16\\\":733,\\\"_22\\\":735,\\\"_24\\\":736,\\\"_26\\\":34,\\\"_27\\\":737},{\\\"_18\\\":734,\\\"_169\\\":10},\\\"Backend For Frontend\\\",\\\"guides/bff.md\\\",\\\"guides/bff\\\",[],{\\\"_16\\\":739,\\\"_22\\\":741,\\\"_24\\\":742,\\\"_26\\\":34,\\\"_27\\\":743},{\\\"_18\\\":740},\\\"Breadcrumbs Guide\\\",\\\"guides/breadcrumbs.md\\\",\\\"guides/breadcrumbs\\\",[],{\\\"_16\\\":745,\\\"_22\\\":747,\\\"_24\\\":748,\\\"_26\\\":34,\\\"_27\\\":749},{\\\"_18\\\":746},\\\"Browser Support\\\",\\\"guides/browser-support.md\\\",\\\"guides/browser-support\\\",[],{\\\"_16\\\":751,\\\"_22\\\":753,\\\"_24\\\":754,\\\"_26\\\":34,\\\"_27\\\":755},{\\\"_18\\\":752},\\\"Client Data\\\",\\\"guides/client-data.md\\\",\\\"guides/client-data\\\",[],{\\\"_16\\\":757,\\\"_22\\\":759,\\\"_24\\\":760,\\\"_26\\\":34,\\\"_27\\\":761},{\\\"_18\\\":758},\\\"Module Constraints\\\",\\\"guides/constraints.md\\\",\\\"guides/constraints\\\",[],{\\\"_16\\\":763,\\\"_22\\\":766,\\\"_24\\\":767,\\\"_26\\\":34,\\\"_27\\\":768},{\\\"_18\\\":764,\\\"_53\\\":765},\\\"Contributing\\\",\\\"Thank you for contributing to Remix! Here's everything you need to know before you open a pull request.\\\",\\\"guides/contributing.md\\\",\\\"guides/contributing\\\",[],{\\\"_16\\\":770,\\\"_22\\\":772,\\\"_24\\\":773,\\\"_26\\\":34,\\\"_27\\\":774},{\\\"_18\\\":771},\\\"CSS Files\\\",\\\"guides/css-files.md\\\",\\\"guides/css-files\\\",[],{\\\"_16\\\":776,\\\"_22\\\":779,\\\"_24\\\":780,\\\"_26\\\":34,\\\"_27\\\":781},{\\\"_18\\\":777,\\\"_53\\\":778},\\\"Data Loading\\\",\\\"One of the primary features of Remix is simplifying interactions with the server to get data into components. This document will help you get the most out of data loading in Remix.\\\",\\\"guides/data-loading.md\\\",\\\"guides/data-loading\\\",[],{\\\"_16\\\":783,\\\"_22\\\":785,\\\"_24\\\":786,\\\"_26\\\":34,\\\"_27\\\":787},{\\\"_18\\\":784},\\\"Data Writes\\\",\\\"guides/data-writes.md\\\",\\\"guides/data-writes\\\",[],{\\\"_16\\\":789,\\\"_22\\\":791,\\\"_24\\\":792,\\\"_26\\\":34,\\\"_27\\\":793},{\\\"_18\\\":790},\\\"Dependency optimization\\\",\\\"guides/dependency-optimization.md\\\",\\\"guides/dependency-optimization\\\",[],{\\\"_16\\\":795,\\\"_22\\\":797,\\\"_24\\\":798,\\\"_26\\\":34,\\\"_27\\\":799},{\\\"_18\\\":796,\\\"_169\\\":10},\\\"Deployment\\\",\\\"guides/deployment.md\\\",\\\"guides/deployment\\\",[],{\\\"_16\\\":801,\\\"_22\\\":803,\\\"_24\\\":804,\\\"_26\\\":34,\\\"_27\\\":805},{\\\"_18\\\":802,\\\"_169\\\":10},\\\"Disabling JavaScript\\\",\\\"guides/disabling-javascript.md\\\",\\\"guides/disabling-javascript\\\",[],{\\\"_16\\\":807,\\\"_22\\\":809,\\\"_24\\\":810,\\\"_26\\\":34,\\\"_27\\\":811},{\\\"_18\\\":808},\\\"Environment Variables\\\",\\\"guides/envvars.md\\\",\\\"guides/envvars\\\",[],{\\\"_16\\\":813,\\\"_22\\\":815,\\\"_24\\\":816,\\\"_26\\\":34,\\\"_27\\\":817},{\\\"_18\\\":814},\\\"Error Handling\\\",\\\"guides/errors.md\\\",\\\"guides/errors\\\",[],{\\\"_16\\\":819,\\\"_22\\\":822,\\\"_24\\\":823,\\\"_26\\\":34,\\\"_27\\\":824},{\\\"_18\\\":820,\\\"_53\\\":821},\\\"FAQs\\\",\\\"Frequently Asked Questions about Remix\\\",\\\"guides/faq.md\\\",\\\"guides/faq\\\",[],{\\\"_16\\\":826,\\\"_22\\\":828,\\\"_24\\\":829,\\\"_26\\\":34,\\\"_27\\\":830},{\\\"_18\\\":827},\\\"File Uploads\\\",\\\"guides/file-uploads.md\\\",\\\"guides/file-uploads\\\",[],{\\\"_16\\\":832,\\\"_22\\\":834,\\\"_24\\\":835,\\\"_26\\\":34,\\\"_27\\\":836},{\\\"_18\\\":833},\\\"Form Validation\\\",\\\"guides/form-validation.md\\\",\\\"guides/form-validation\\\",[],{\\\"_16\\\":838,\\\"_22\\\":840,\\\"_24\\\":841,\\\"_26\\\":34,\\\"_27\\\":842},{\\\"_18\\\":839},\\\"Gotchas\\\",\\\"guides/gotchas.md\\\",\\\"guides/gotchas\\\",[],{\\\"_16\\\":844,\\\"_22\\\":846,\\\"_24\\\":847,\\\"_26\\\":34,\\\"_27\\\":848},{\\\"_18\\\":845,\\\"_169\\\":10},\\\"Index Query Param\\\",\\\"guides/index-query-param.md\\\",\\\"guides/index-query-param\\\",[],{\\\"_16\\\":850,\\\"_22\\\":852,\\\"_24\\\":853,\\\"_26\\\":34,\\\"_27\\\":854},{\\\"_18\\\":851},\\\"Lazy Route Discovery\\\",\\\"guides/lazy-route-discovery.md\\\",\\\"guides/lazy-route-discovery\\\",[],{\\\"_16\\\":856,\\\"_22\\\":858,\\\"_24\\\":859,\\\"_26\\\":34,\\\"_27\\\":860},{\\\"_18\\\":857},\\\"Local TLS\\\",\\\"guides/local-tls.md\\\",\\\"guides/local-tls\\\",[],{\\\"_16\\\":862,\\\"_22\\\":864,\\\"_24\\\":865,\\\"_26\\\":34,\\\"_27\\\":866},{\\\"_18\\\":863},\\\"Manual Dev Server\\\",\\\"guides/manual-mode.md\\\",\\\"guides/manual-mode\\\",[],{\\\"_16\\\":868,\\\"_22\\\":871,\\\"_24\\\":872,\\\"_26\\\":34,\\\"_27\\\":873},{\\\"_18\\\":869,\\\"_53\\\":870},\\\"MDX\\\",\\\"Remix makes integrating MDX into your project a breeze with built in routes and \\\\\\\"import\\\\\\\" support.\\\",\\\"guides/mdx.md\\\",\\\"guides/mdx\\\",[],{\\\"_16\\\":875,\\\"_22\\\":878,\\\"_24\\\":879,\\\"_26\\\":34,\\\"_27\\\":880},{\\\"_18\\\":876,\\\"_53\\\":877},\\\"Migrating from React Router\\\",\\\"Migrating your React Router app to Remix can be done all at once or in stages. This guide will walk you through an iterative approach to get your app running quickly.\\\",\\\"guides/migrating-react-router-app.md\\\",\\\"guides/migrating-react-router-app\\\",[],{\\\"_16\\\":882,\\\"_22\\\":884,\\\"_24\\\":885,\\\"_26\\\":34,\\\"_27\\\":886},{\\\"_18\\\":883},\\\"Not Found Handling\\\",\\\"guides/not-found.md\\\",\\\"guides/not-found\\\",[],{\\\"_16\\\":888,\\\"_22\\\":890,\\\"_24\\\":891,\\\"_26\\\":34,\\\"_27\\\":892},{\\\"_18\\\":889},\\\"Performance\\\",\\\"guides/performance.md\\\",\\\"guides/performance\\\",[],{\\\"_16\\\":894,\\\"_22\\\":896,\\\"_24\\\":897,\\\"_26\\\":34,\\\"_27\\\":898},{\\\"_18\\\":895},\\\"Presets\\\",\\\"guides/presets.md\\\",\\\"guides/presets\\\",[],{\\\"_16\\\":900,\\\"_22\\\":902,\\\"_24\\\":903,\\\"_26\\\":34,\\\"_27\\\":904},{\\\"_18\\\":901},\\\"Resource Routes\\\",\\\"guides/resource-routes.md\\\",\\\"guides/resource-routes\\\",[],{\\\"_16\\\":906,\\\"_22\\\":908,\\\"_24\\\":909,\\\"_26\\\":34,\\\"_27\\\":910},{\\\"_18\\\":907},\\\"Server Bundles\\\",\\\"guides/server-bundles.md\\\",\\\"guides/server-bundles\\\",[],{\\\"_16\\\":912,\\\"_22\\\":914,\\\"_24\\\":915,\\\"_26\\\":34,\\\"_27\\\":916},{\\\"_18\\\":913},\\\"Single Fetch\\\",\\\"guides/single-fetch.md\\\",\\\"guides/single-fetch\\\",[],{\\\"_16\\\":918,\\\"_22\\\":920,\\\"_24\\\":921,\\\"_26\\\":34,\\\"_27\\\":922},{\\\"_18\\\":919},\\\"SPA Mode\\\",\\\"guides/spa-mode.md\\\",\\\"guides/spa-mode\\\",[],{\\\"_16\\\":924,\\\"_22\\\":927,\\\"_24\\\":928,\\\"_26\\\":34,\\\"_27\\\":929},{\\\"_18\\\":925,\\\"_53\\\":926},\\\"Streaming\\\",\\\"When, why, and how to stream with React 18 and Remix's deferred API.\\\",\\\"guides/streaming.md\\\",\\\"guides/streaming\\\",[],{\\\"_16\\\":931,\\\"_22\\\":934,\\\"_24\\\":935,\\\"_26\\\":34,\\\"_27\\\":936},{\\\"_18\\\":932,\\\"_53\\\":933},\\\"Templates\\\",\\\"The quickest way to get rocking and rolling with Remix\\\",\\\"guides/templates.md\\\",\\\"guides/templates\\\",[],{\\\"_16\\\":938,\\\"_22\\\":940,\\\"_24\\\":941,\\\"_26\\\":34,\\\"_27\\\":942},{\\\"_18\\\":939,\\\"_169\\\":10},\\\"TypeScript\\\",\\\"guides/typescript.md\\\",\\\"guides/typescript\\\",[],{\\\"_16\\\":944,\\\"_22\\\":946,\\\"_24\\\":947,\\\"_26\\\":34,\\\"_27\\\":948},{\\\"_18\\\":945},\\\"Vite\\\",\\\"guides/vite.md\\\",\\\"guides/vite\\\",[],\\\"routes/docs.$\\\",{\\\"_951\\\":952},\\\"doc\\\",{\\\"_16\\\":953,\\\"_22\\\":954,\\\"_955\\\":956,\\\"_24\\\":957,\\\"_958\\\":959,\\\"_27\\\":977},{\\\"_18\\\":92,\\\"_20\\\":46},\\\"docs/discussion/routes.md\\\",\\\"html\\\",\\\"\\u003ch1 id=\\\\\\\"route-configuration\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#route-configuration\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eRoute Configuration\\u003c/h1\\u003e\\\\n\\u003cp\\u003eOne of the foundational concepts in Remix's routing system is the use of nested routes, an approach that traces its roots back to Ember.js. With nested routes, segments of the URL are coupled to both data dependencies and the UI's component hierarchy. A URL like \\u003ccode\\u003e/sales/invoices/102000\\u003c/code\\u003e not only reveals a clear path in the application but also delineates the relationships and dependencies for different components.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"modular-design\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#modular-design\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eModular Design\\u003c/h2\\u003e\\\\n\\u003cp\\u003eNested routes provide clarity by segmenting URLs into multiple parts. Each segment directly correlates with a particular data requirement and component. For instance, in the URL \\u003ccode\\u003e/sales/invoices/102000\\u003c/code\\u003e, each segment - \\u003ccode\\u003esales\\u003c/code\\u003e, \\u003ccode\\u003einvoices\\u003c/code\\u003e, and \\u003ccode\\u003e102000\\u003c/code\\u003e - can be associated with specific data points and UI sections, making it intuitive to manage in the codebase.\\u003c/p\\u003e\\\\n\\u003cp\\u003eA feature of nested routing is the ability for several routes in the nested route tree to match a single URL. This granularity ensures that each route is primarily focused on its specific URL segment and related slice of UI. This approach champions the principles of modularity and separation of concerns, ensuring each route remains focused on its core responsibilities.\\u003c/p\\u003e\\\\n\\u003ciframe src=\\\\\\\"/_docs/routing\\\\\\\" class=\\\\\\\"w-full aspect-[1/1] rounded-lg overflow-hidden pb-4\\\\\\\"\\u003e\\u003c/iframe\\u003e\\\\n\\u003ch2 id=\\\\\\\"parallel-loading\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#parallel-loading\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eParallel Loading\\u003c/h2\\u003e\\\\n\\u003cp\\u003eIn some web applications, the sequential loading of data and assets can sometimes lead to an artificially slow user experience. Even when data dependencies aren't interdependent, they may be loaded sequentially because they are coupled to rendering hierarchy, creating an undesirable chain of requests.\\u003c/p\\u003e\\\\n\\u003cp\\u003eRemix leverages its nested routing system to optimize load times. When a URL matches multiple routes, Remix will load the required data and assets for all matching routes in parallel. By doing this, Remix effectively sidesteps the conventional pitfall of chained request sequences.\\u003c/p\\u003e\\\\n\\u003cp\\u003eThis strategy, combined with modern browsers' ability to handle multiple concurrent requests efficiently, positions Remix as a front-runner in delivering highly responsive and swift web applications. It's not just about making your data fetching fast; it's about fetching it in an organized way to provide the best possible experience for the end user.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"conventional-route-configuration\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#conventional-route-configuration\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eConventional Route Configuration\\u003c/h2\\u003e\\\\n\\u003cp\\u003eRemix introduces a key convention to help streamline the routing process: the \\u003ccode\\u003eapp/routes\\u003c/code\\u003e folder. When a developer introduces a file within this folder, Remix inherently understands it as a route. This convention simplifies the process of defining routes, associating them with URLs, and rendering the associated components.\\u003c/p\\u003e\\\\n\\u003cp\\u003eHere's a sample directory that uses the routes folder convention:\\u003c/p\\u003e\\\\n\\u003cpre\\u003e\\u003ccode class=\\\\\\\"language-text\\\\\\\"\\u003eapp/\\\\nβ”œβ”€β”€ routes/\\\\nβ”‚ β”œβ”€β”€ _index.tsx\\\\nβ”‚ β”œβ”€β”€ about.tsx\\\\nβ”‚ β”œβ”€β”€ concerts._index.tsx\\\\nβ”‚ β”œβ”€β”€ concerts.$city.tsx\\\\nβ”‚ β”œβ”€β”€ concerts.trending.tsx\\\\nβ”‚ └── concerts.tsx\\\\n└── root.tsx\\\\n\\u003c/code\\u003e\\u003c/pre\\u003e\\\\n\\u003cp\\u003eAll the routes that start with \\u003ccode\\u003eapp/routes/concerts.\\u003c/code\\u003e will be child routes of \\u003ccode\\u003eapp/routes/concerts.tsx\\u003c/code\\u003e.\\u003c/p\\u003e\\\\n\\u003ctable\\u003e\\\\n\\u003cthead\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003cth\\u003eURL\\u003c/th\\u003e\\\\n\\u003cth\\u003eMatched Route\\u003c/th\\u003e\\\\n\\u003cth\\u003eLayout\\u003c/th\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003c/thead\\u003e\\\\n\\u003ctbody\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e/\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/_index.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/root.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e/about\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/about.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/root.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e/concerts\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/concerts._index.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/concerts.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e/concerts/trending\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/concerts.trending.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/concerts.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e/concerts/salt-lake-city\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/concerts.$city.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/concerts.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003c/tbody\\u003e\\\\n\\u003c/table\\u003e\\\\n\\u003ch2 id=\\\\\\\"conventional-route-folders\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#conventional-route-folders\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eConventional Route Folders\\u003c/h2\\u003e\\\\n\\u003cp\\u003eFor routes that require additional modules or assets, a folder inside of \\u003ccode\\u003eapp/routes\\u003c/code\\u003e with a \\u003ccode\\u003eroute.tsx\\u003c/code\\u003e file can be used. This method:\\u003c/p\\u003e\\\\n\\u003cul\\u003e\\\\n\\u003cli\\u003e\\u003cstrong\\u003eCo-locates Modules\\u003c/strong\\u003e: It gathers all elements connected to a particular route, ensuring logic, styles, and components are closely knit.\\u003c/li\\u003e\\\\n\\u003cli\\u003e\\u003cstrong\\u003eSimplifies Imports\\u003c/strong\\u003e: With related modules in one place, managing imports becomes straightforward, enhancing code maintainability.\\u003c/li\\u003e\\\\n\\u003cli\\u003e\\u003cstrong\\u003eFacilitates Automatic Code Organization\\u003c/strong\\u003e: Using the \\u003ccode\\u003eroute.tsx\\u003c/code\\u003e setup inherently promotes a well-organized codebase, beneficial as the application scales.\\u003c/li\\u003e\\\\n\\u003c/ul\\u003e\\\\n\\u003cp\\u003eThe same routes from above could instead be organized like this:\\u003c/p\\u003e\\\\n\\u003cpre\\u003e\\u003ccode class=\\\\\\\"language-text\\\\\\\"\\u003eapp/\\\\nβ”œβ”€β”€ routes/\\\\nβ”‚ β”œβ”€β”€ _index/\\\\nβ”‚ β”‚ β”œβ”€β”€ signup-form.tsx\\\\nβ”‚ β”‚ └── route.tsx\\\\nβ”‚ β”œβ”€β”€ about/\\\\nβ”‚ β”‚ β”œβ”€β”€ header.tsx\\\\nβ”‚ β”‚ └── route.tsx\\\\nβ”‚ β”œβ”€β”€ concerts/\\\\nβ”‚ β”‚ β”œβ”€β”€ favorites-cookie.ts\\\\nβ”‚ β”‚ └── route.tsx\\\\nβ”‚ β”œβ”€β”€ concerts.$city/\\\\nβ”‚ β”‚ └── route.tsx\\\\nβ”‚ β”œβ”€β”€ concerts._index/\\\\nβ”‚ β”‚ β”œβ”€β”€ featured.tsx\\\\nβ”‚ β”‚ └── route.tsx\\\\nβ”‚ └── concerts.trending/\\\\nβ”‚ β”œβ”€β”€ card.tsx\\\\nβ”‚ β”œβ”€β”€ route.tsx\\\\nβ”‚ └── sponsored.tsx\\\\n└── root.tsx\\\\n\\u003c/code\\u003e\\u003c/pre\\u003e\\\\n\\u003cp\\u003eYou can read more about the specific patterns in the file names and other features in the \\u003ca href=\\\\\\\"../file-conventions/routes\\\\\\\"\\u003eRoute File Conventions\\u003c/a\\u003e reference.\\u003c/p\\u003e\\\\n\\u003cp\\u003eOnly the folders directly beneath \\u003ccode\\u003eapp/routes\\u003c/code\\u003e will be registered as a route. Deeply nested folders are ignored. The file at \\u003ccode\\u003eapp/routes/about/header/route.tsx\\u003c/code\\u003e will not create a route.\\u003c/p\\u003e\\\\n\\u003cpre\\u003e\\u003ccode class=\\\\\\\"language-text\\\\\\\"\\u003eapp/\\\\nβ”œβ”€β”€ routes/\\\\nβ”‚ └── about/\\\\nβ”‚ β”œβ”€β”€ header/\\\\nβ”‚ β”‚ └── route.tsx\\\\nβ”‚ └── route.tsx\\\\n└── root.tsx\\\\n\\u003c/code\\u003e\\u003c/pre\\u003e\\\\n\\u003ch2 id=\\\\\\\"manual-route-configuration\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#manual-route-configuration\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eManual Route Configuration\\u003c/h2\\u003e\\\\n\\u003cp\\u003eWhile the \\u003ccode\\u003eapp/routes\\u003c/code\\u003e folder offers a convenient convention for developers, Remix appreciates that \\u003ca href=\\\\\\\"../file-conventions/routes#disclaimer\\\\\\\"\\u003eone size doesn't fit all\\u003c/a\\u003e. There are times when the provided convention might not align with specific project requirements or a developer's preferences. In such cases, Remix allows for manual route configuration via \\u003ca href=\\\\\\\"../file-conventions/vite-config#routes\\\\\\\"\\u003e\\u003ccode\\u003evite.config.ts\\u003c/code\\u003e\\u003c/a\\u003e. This flexibility ensures developers can structure their application in a way that makes sense for their project.\\u003c/p\\u003e\\\\n\\u003cp\\u003e\\u003cdocs-warning\\u003eIf you have not yet migrated to \\u003ca href=\\\\\\\"../guides/vite\\\\\\\"\\u003eVite\\u003c/a\\u003e and are still using the \\u003ca href=\\\\\\\"../guides/vite#classic-remix-compiler-vs-remix-vite\\\\\\\"\\u003eClassic Remix Compiler\\u003c/a\\u003e, you can configure routes manually in your \\u003ca href=\\\\\\\"../file-conventions/remix-config\\\\\\\"\\u003e\\u003ccode\\u003eremix.config.js\\u003c/code\\u003e\\u003c/a\\u003e file.\\u003c/docs-warning\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eA common way to structure an app is by top-level features folders. Consider that routes related to a particular theme, like concerts, likely share several modules. Organizing them under a single folder makes sense:\\u003c/p\\u003e\\\\n\\u003cpre\\u003e\\u003ccode class=\\\\\\\"language-text\\\\\\\"\\u003eapp/\\\\nβ”œβ”€β”€ about/\\\\nβ”‚ └── route.tsx\\\\nβ”œβ”€β”€ concerts/\\\\nβ”‚ β”œβ”€β”€ card.tsx\\\\nβ”‚ β”œβ”€β”€ city.tsx\\\\nβ”‚ β”œβ”€β”€ favorites-cookie.ts\\\\nβ”‚ β”œβ”€β”€ home.tsx\\\\nβ”‚ β”œβ”€β”€ layout.tsx\\\\nβ”‚ β”œβ”€β”€ sponsored.tsx\\\\nβ”‚ └── trending.tsx\\\\nβ”œβ”€β”€ home/\\\\nβ”‚ β”œβ”€β”€ header.tsx\\\\nβ”‚ └── route.tsx\\\\n└── root.tsx\\\\n\\u003c/code\\u003e\\u003c/pre\\u003e\\\\n\\u003cp\\u003eTo configure this structure into the same URLs as the previous examples, you can use the \\u003ccode\\u003eroutes\\u003c/code\\u003e function in \\u003ccode\\u003evite.config.ts\\u003c/code\\u003e:\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003evitePlugin\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eas\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eremix\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/dev\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003edefineConfig\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003evite\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003edefault\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003edefineConfig\\u003c/span\\u003e({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e plugins: [\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eremix\\u003c/span\\u003e({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eroutes\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003edefineRoutes\\u003c/span\\u003e) {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003edefineRoutes\\u003c/span\\u003e((\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eroute\\u003c/span\\u003e) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eroute\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e/\\u003c/span\\u003e\\\\\\\", \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003ehome/route.tsx\\u003c/span\\u003e\\\\\\\", { index: \\u003cspan style=\\\\\\\"color: var(--base09)\\\\\\\"\\u003etrue\\u003c/span\\u003e });\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eroute\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eabout\\u003c/span\\u003e\\\\\\\", \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eabout/route.tsx\\u003c/span\\u003e\\\\\\\");\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eroute\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003econcerts\\u003c/span\\u003e\\\\\\\", \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003econcerts/layout.tsx\\u003c/span\\u003e\\\\\\\", () \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eroute\\u003c/span\\u003e(\\\\\\\"\\\\\\\", \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003econcerts/home.tsx\\u003c/span\\u003e\\\\\\\", { index: \\u003cspan style=\\\\\\\"color: var(--base09)\\\\\\\"\\u003etrue\\u003c/span\\u003e });\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eroute\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003etrending\\u003c/span\\u003e\\\\\\\", \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003econcerts/trending.tsx\\u003c/span\\u003e\\\\\\\");\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eroute\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e:city\\u003c/span\\u003e\\\\\\\", \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003econcerts/city.tsx\\u003c/span\\u003e\\\\\\\");\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e });\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e });\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e },\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e }),\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\u003e ],\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"20\\\\\\\"\\u003e});\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eRemix's route configuration approach blends convention with flexibility. You can use the \\u003ccode\\u003eapp/routes\\u003c/code\\u003e folder for an easy, organized way to set up your routes. If you want more control, dislike the file names, or have unique needs, there's \\u003ccode\\u003evite.config.ts\\u003c/code\\u003e. It is expected that many apps forgo the routes folder convention in favor of \\u003ccode\\u003evite.config.ts\\u003c/code\\u003e.\\u003c/p\\u003e\\\",\\\"docs/discussion/routes\\\",\\\"headings\\\",[960,965,968,971,974],{\\\"_961\\\":962,\\\"_955\\\":963,\\\"_24\\\":964},\\\"headingLevel\\\",\\\"h2\\\",\\\"Modular Design\\\",\\\"modular-design\\\",{\\\"_961\\\":962,\\\"_955\\\":966,\\\"_24\\\":967},\\\"Parallel Loading\\\",\\\"parallel-loading\\\",{\\\"_961\\\":962,\\\"_955\\\":969,\\\"_24\\\":970},\\\"Conventional Route Configuration\\\",\\\"conventional-route-configuration\\\",{\\\"_961\\\":962,\\\"_955\\\":972,\\\"_24\\\":973},\\\"Conventional Route Folders\\\",\\\"conventional-route-folders\\\",{\\\"_961\\\":962,\\\"_955\\\":975,\\\"_24\\\":976},\\\"Manual Route Configuration\\\",\\\"manual-route-configuration\\\",[],\\\"actionData\\\",\\\"errors\\\"]\\n\");function $RC(a,b){a=document.getElementById(a);b=document.getElementById(b);b.parentNode.removeChild(b);if(a){a=a.previousSibling;var f=a.parentNode,c=a.nextSibling,e=0;do{if(c\u0026\u00268===c.nodeType){var d=c.data;if(\"/$\"===d)if(0===e)break;else e--;else\"$\"!==d\u0026\u0026\"$?\"!==d\u0026\u0026\"$!\"!==d||e++}d=c.nextSibling;f.removeChild(c);c=d}while(c);for(;b.firstChild;)f.insertBefore(b.firstChild,c);a.data=\"$\";a._reactRetry\u0026\u0026a._reactRetry()}};$RC(\"B:0\",\"S:0\")window.__reactRouterContext.streamController.close();$RC(\"B:1\",\"S:1\")", "url": "https://v2.remix.run/docs/discussion/routes", "metadata": { "description": "", "headings": [ "Route Configuration", "Modular Design", "Parallel Loading", "Conventional Route Configuration", "Conventional Route Folders", "Manual Route Configuration" ], "images": [ "/assets/icons-CZ8v8NWl.svg" ], "links": [ "/", "/docs", "https://remix.run/blog", "/resources", "https://reactrouter.com/home", "https://github.com/remix-run/remix/tree/v2", "https://rmx.as/discord", "/docs/start/quickstart", "/docs/start/tutorial", "/docs/start/v2", "/docs/start/community", "/docs/start/future-flags", "/docs/start/changelog", "/docs/discussion/introduction", "/docs/discussion/runtimes", "/docs/discussion/routes", "/docs/discussion/data-flow", "/docs/discussion/server-vs-client", "/docs/discussion/react-router", "/docs/discussion/progressive-enhancement", "/docs/discussion/pending-ui", "/docs/discussion/state-management", "/docs/discussion/concurrency", "/docs/discussion/form-vs-fetcher", "/docs/discussion/hot-module-replacement", "/docs/discussion/resubmissions", "/docs/file-conventions/-client", "/docs/file-conventions/-server", "/docs/file-conventions/asset-imports", "/docs/file-conventions/entry.client", "/docs/file-conventions/entry.server", "/docs/file-conventions/root", "/docs/file-conventions/routes", "/docs/file-conventions/vite-config", "/docs/route/action", "/docs/route/client-action", "/docs/route/client-loader", "/docs/route/component", "/docs/route/error-boundary", "/docs/route/handle", "/docs/route/headers", "/docs/route/hydrate-fallback", "/docs/route/links", "/docs/route/loader", "/docs/route/meta", "/docs/route/should-revalidate", "/docs/components/await", "/docs/components/form", "/docs/components/link", "/docs/components/links", "/docs/components/live-reload", "/docs/components/meta", "/docs/components/nav-link", "/docs/components/outlet", "/docs/components/prefetch-page-links", "/docs/components/scripts", "/docs/components/scroll-restoration", "/docs/hooks/use-action-data", "/docs/hooks/use-async-error", "/docs/hooks/use-async-value", "/docs/hooks/use-before-unload", "/docs/hooks/use-blocker", "/docs/hooks/use-fetcher", "/docs/hooks/use-fetchers", "/docs/hooks/use-form-action", "/docs/hooks/use-href", "/docs/hooks/use-loader-data", "/docs/hooks/use-location", "/docs/hooks/use-matches", "/docs/hooks/use-navigate", "/docs/hooks/use-navigation", "/docs/hooks/use-navigation-type", "/docs/hooks/use-outlet", "/docs/hooks/use-outlet-context", "/docs/hooks/use-params", "/docs/hooks/use-prompt", "/docs/hooks/use-resolved-path", "/docs/hooks/use-revalidator", "/docs/hooks/use-route-error", "/docs/hooks/use-route-loader-data", "/docs/hooks/use-search-params", "/docs/hooks/use-submit", "/docs/hooks/use-view-transition-state", "/docs/utils/cookies", "/docs/utils/create-remix-stub", "/docs/utils/data", "/docs/utils/defer", "/docs/utils/is-route-error-response", "/docs/utils/json", "/docs/utils/parse-multipart-form-data", "/docs/utils/redirect", "/docs/utils/redirectDocument", "/docs/utils/replace", "/docs/utils/sessions", "/docs/utils/unstable-create-file-upload-handler", "/docs/utils/unstable-create-memory-upload-handler", "/docs/styling/bundling", "/docs/styling/css", "/docs/styling/css-imports", "/docs/styling/css-in-js", "/docs/styling/css-modules", "/docs/styling/postcss", "/docs/styling/tailwind", "/docs/styling/vanilla-extract", "/docs/other-api/dev", "/docs/other-api/adapter", "/docs/other-api/serve", "/docs/other-api/create-remix", "/docs/other-api/node", "/docs/other-api/testing", "/docs/guides/accessibility", "/docs/guides/api-development-strategy", "/docs/guides/api-routes", "/docs/guides/bff", "/docs/guides/breadcrumbs", "/docs/guides/browser-support", "/docs/guides/client-data", "/docs/guides/constraints", "/docs/guides/contributing", "/docs/guides/css-files", "/docs/guides/data-loading", "/docs/guides/data-writes", "/docs/guides/dependency-optimization", "/docs/guides/deployment", "/docs/guides/disabling-javascript", "/docs/guides/envvars", "/docs/guides/errors", "/docs/guides/faq", "/docs/guides/file-uploads", "/docs/guides/form-validation", "/docs/guides/gotchas", "/docs/guides/index-query-param", "/docs/guides/lazy-route-discovery", "/docs/guides/local-tls", "/docs/guides/manual-mode", "/docs/guides/mdx", "/docs/guides/migrating-react-router-app", "/docs/guides/not-found", "/docs/guides/performance", "/docs/guides/presets", "/docs/guides/resource-routes", "/docs/guides/server-bundles", "/docs/guides/single-fetch", "/docs/guides/spa-mode", "/docs/guides/streaming", "/docs/guides/templates", "/docs/guides/typescript", "/docs/guides/vite", "/docs/discussion/routes/#modular-design", "/docs/discussion/routes/#parallel-loading", "/docs/discussion/routes/#conventional-route-configuration", "/docs/discussion/routes/#conventional-route-folders", "/docs/discussion/routes/#manual-route-configuration", "../file-conventions/routes", "../file-conventions/routes#disclaimer", "../file-conventions/vite-config#routes", "../guides/vite", "../guides/vite#classic-remix-compiler-vs-remix-vite", "../file-conventions/remix-config", "https://remix.run", "https://opensource.org/licenses/MIT", "https://github.com/remix-run/remix-v2-website/edit/main/data/docs/discussion/routes.md" ] }, "hash": "6fb75fb5190f936f95e25c1a748a3218169b4019f41bbbd0183011ceedbd1b68", "timestamp": "2026-02-23T11:36:17.647140727+01:00" }