mirror of
https://github.com/Dvorinka/Devour.git
synced 2026-06-04 12:33:04 +00:00
211 lines
111 KiB
JSON
211 lines
111 KiB
JSON
{
|
|
"id": "ea23df76f6b19fe71c00f254",
|
|
"source": "remix:routes",
|
|
"type": "html",
|
|
"title": "Route File Naming | Remix",
|
|
"content": "DocsBlogResourcesReact Router v7 has been released. View the docsDocsBlogResourcesView code on GitHubChat on DiscordReact Router v7 has been released. View the docsRoute File NamingGetting 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 pageDisclaimerRoot RouteBasic RoutesDot DelimitersDynamic SegmentsNested RoutesNested URLs without Layout NestingNested Layouts without Nested URLsOptional SegmentsSplat RoutesEscaping Special CharactersFolders for OrganizationScalingOn this pageDisclaimerRoot RouteBasic RoutesDot DelimitersDynamic SegmentsNested RoutesNested URLs without Layout NestingNested Layouts without Nested URLsOptional SegmentsSplat RoutesEscaping Special CharactersFolders for OrganizationScalingRoute File Naming While you can configure routes via the \"routes\" plugin option, most routes are created with this file system convention. Add a file, get a route. Please note that you can use either .js, .jsx, .ts or .tsx file extensions. We'll stick with .tsx in the examples to avoid duplication. Dilum Sanjaya made an awesome visualization of how routes in the file system map to the URL in your app that might help you understand these conventions. Disclaimer Before we go too far into the Remix convention, though, we'd like to point out that file-based routing is an incredibly subjective idea. Some folks love the \"flat\" routes idea, some folks hate it and would prefer nesting routes in folders. Some folks simply hate file-based routing and would prefer to configure routes via JSON. Some folks would prefer to configure routes via JSX like they did in their React Router SPA's. The point is, we are well aware of this and from the get-go, Remix has always given you a first-class way to opt-out via the routes/ignoredRouteFiles and configure your routes manually. But, there has to be some default so that folks can get up and running quickly and easily - and we think that the flat routes convention document below is a pretty good default that scales well for small-to-medium sized apps. Large applications with hundreds or thousands of routes will always be a bit chaotic no matter what convention you use — and the idea is that via the routes config, you get to build exactly the convention that works best for your application/team. It would be quite literally impossible for Remix to have a default convention that made everyone happy. We'd much rather give you a fairly straightforward default and then let the community build any number of conventions you can pick and choose from. So, before we dive into the details of the Remix default convention, here are some community alternatives you can check out if you decide that our default is not your cup of tea. remix-flat-routes - The Remix default is basically a simplified version of this package. The author has continued to iterate on and evolve this package, so if you generally like the \"flat routes\" idea but want a bit more power (including a hybrid approach of files and folders), definitely check this one out. remix-custom-routes - If you want even more customization, this package lets you define that types of files should be treated as routes. This lets you go beyond the simple flat/nested concept and do something such as \"any file with an extension of .route.tsx is a route\". remix-json-routes - If you just want to specify your routes via a config file, this is your jam — provide Remix a JSON object with your routes and skip the flat/nested concept entirely. There's even a JSX option in there too. Root Route app/ ├── routes/ └── root.tsx The file in app/root.tsx is your root layout, or \"root route\" (very sorry for those of you who pronounce those words the same way!). It works just like all other routes, so you can export a loader, action, etc. The root route typically looks something like this. It serves as the root layout of the entire app, all other routes will render inside the \u003cOutlet /\u003e. import { Links, Meta, Outlet, Scripts, ScrollRestoration, } from \"@remix-run/react\"; export default function Root() { return ( \u003chtml lang=\"en\"\u003e \u003chead\u003e \u003cLinks /\u003e \u003cMeta /\u003e \u003c/head\u003e \u003cbody\u003e \u003cOutlet /\u003e \u003cScrollRestoration /\u003e \u003cScripts /\u003e \u003c/body\u003e \u003c/html\u003e ); } Basic Routes Any JavaScript or TypeScript files in the app/routes directory will become routes in your application. The filename maps to the route's URL pathname, except for _index.tsx which is the index route for the root route. app/ ├── routes/ │ ├── _index.tsx │ └── about.tsx └── root.tsx URL Matched Routes / app/routes/_index.tsx /about app/routes/about.tsx Note that these routes will be rendered in the outlet of app/root.tsx because of nested routing. Dot Delimiters Adding a . to a route filename will create a / in the URL. app/ ├── routes/ │ ├── _index.tsx │ ├── about.tsx │ ├── concerts.trending.tsx │ ├── concerts.salt-lake-city.tsx │ └── concerts.san-diego.tsx └── root.tsx URL Matched Route / app/routes/_index.tsx /about app/routes/about.tsx /concerts/trending app/routes/concerts.trending.tsx /concerts/salt-lake-city app/routes/concerts.salt-lake-city.tsx /concerts/san-diego app/routes/concerts.san-diego.tsx The dot delimiter also creates nesting, see the nesting section for more information. Dynamic Segments Usually your URLs aren't static but data-driven. Dynamic segments allow you to match segments of the URL and use that value in your code. You create them with the $ prefix. app/ ├── routes/ │ ├── _index.tsx │ ├── about.tsx │ ├── concerts.$city.tsx │ └── concerts.trending.tsx └── root.tsx URL Matched Route / app/routes/_index.tsx /about app/routes/about.tsx /concerts/trending app/routes/concerts.trending.tsx /concerts/salt-lake-city app/routes/concerts.$city.tsx /concerts/san-diego app/routes/concerts.$city.tsx Remix will parse the value from the URL and pass it to various APIs. We call these values \"URL Parameters\". The most useful places to access the URL params are in loaders and actions. export async function loader({ params, }: LoaderFunctionArgs) { return fakeDb.getAllConcertsForCity(params.city); } You'll note the property name on the params object maps directly to the name of your file: $city.tsx becomes params.city. Routes can have multiple dynamic segments, like concerts.$city.$date, both are accessed on the params object by name: export async function loader({ params, }: LoaderFunctionArgs) { return fake.db.getConcerts({ date: params.date, city: params.city, }); } See the routing guide for more information. Nested Routes Nested Routing is the general idea of coupling segments of the URL to component hierarchy and data. You can read more about it in the Routing Guide. You create nested routes with dot delimiters. If the filename before the . matches another route filename, it automatically becomes a child route to the matching parent. Consider these routes: 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 and render inside the parent route's outlet_component. 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 Note you typically want to add an index route when you add nested routes so that something renders inside the parent's outlet when users visit the parent URL directly. For example, if the URL is /concerts/salt-lake-city then the UI hierarchy will look like this: \u003cRoot\u003e \u003cConcerts\u003e \u003cCity /\u003e \u003c/Concerts\u003e \u003c/Root\u003e Nested URLs without Layout Nesting Sometimes you want the URL to be nested, but you don't want the automatic layout nesting. You can opt out of nesting with a trailing underscore on the parent segment: app/ ├── routes/ │ ├── _index.tsx │ ├── about.tsx │ ├── concerts.$city.tsx │ ├── concerts.trending.tsx │ ├── concerts.tsx │ └── concerts_.mine.tsx └── root.tsx URL Matched Route Layout / app/routes/_index.tsx app/root.tsx /about app/routes/about.tsx app/root.tsx /concerts/mine app/routes/concerts_.mine.tsx app/root.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 Note that /concerts/mine does not nest with app/routes/concerts.tsx anymore, but app/root.tsx. The trailing_ underscore creates a path segment, but it does not create layout nesting. Think of the trailing_ underscore as the long bit at the end of your parent's signature, writing you out of the will, removing the segment that follows from the layout nesting. Nested Layouts without Nested URLs We call these Pathless Routes Sometimes you want to share a layout with a group of routes without adding any path segments to the URL. A common example is a set of authentication routes that have a different header/footer than the public pages or the logged-in-app experience. You can do this with a _leading underscore. app/ ├── routes/ │ ├── _auth.login.tsx │ ├── _auth.register.tsx │ ├── _auth.tsx │ ├── _index.tsx │ ├── concerts.$city.tsx │ └── concerts.tsx └── root.tsx URL Matched Route Layout / app/routes/_index.tsx app/root.tsx /login app/routes/_auth.login.tsx app/routes/_auth.tsx /register app/routes/_auth.register.tsx app/routes/_auth.tsx /concerts app/routes/concerts.tsx app/root.tsx /concerts/salt-lake-city app/routes/concerts.$city.tsx app/routes/concerts.tsx Think of the _leading underscore as a blanket you're pulling over the filename, hiding the filename from the URL. Optional Segments Wrapping a route segment in parentheses will make the segment optional. app/ ├── routes/ │ ├── ($lang)._index.tsx │ ├── ($lang).$productId.tsx │ └── ($lang).categories.tsx └── root.tsx URL Matched Route / app/routes/($lang)._index.tsx /categories app/routes/($lang).categories.tsx /en/categories app/routes/($lang).categories.tsx /fr/categories app/routes/($lang).categories.tsx /american-flag-speedo app/routes/($lang)._index.tsx /en/american-flag-speedo app/routes/($lang).$productId.tsx /fr/american-flag-speedo app/routes/($lang).$productId.tsx You may wonder why /american-flag-speedo is matching the ($lang)._index.tsx route instead of ($lang).$productId.tsx. This is because when you have an optional dynamic param segment followed by another dynamic param, Remix cannot reliably determine if a single-segment URL such as /american-flag-speedo should match /:lang /:productId. Optional segments match eagerly and thus it will match /:lang. If you have this type of setup, it's recommended to look at params.lang in the ($lang)._index.tsx loader and redirect to /:lang/american-flag-speedo for the current/default language if params.lang is not a valid language code. Splat Routes While dynamic segments match a single path segment (the stuff between two / in a URL), a splat route will match the rest of a URL, including the slashes. app/ ├── routes/ │ ├── _index.tsx │ ├── $.tsx │ ├── about.tsx │ └── files.$.tsx └── root.tsx URL Matched Route / app/routes/_index.tsx /about app/routes/about.tsx /beef/and/cheese app/routes/$.tsx /files app/routes/files.$.tsx /files/talks/remix-conf_old.pdf app/routes/files.$.tsx /files/talks/remix-conf_final.pdf app/routes/files.$.tsx /files/talks/remix-conf-FINAL-MAY_2022.pdf app/routes/files.$.tsx Similar to dynamic route parameters, you can access the value of the matched path on the splat route's params with the \"*\" key. export async function loader({ params, }: LoaderFunctionArgs) { const filePath = params[\"*\"]; return fake.getFileInfo(filePath); } Escaping Special Characters If you want one of the special characters Remix uses for these route conventions to actually be a part of the URL, you can escape the conventions with [] characters. Filename URL app/routes/sitemap[.]xml.tsx /sitemap.xml app/routes/[sitemap.xml].tsx /sitemap.xml app/routes/weird-url.[_index].tsx /weird-url/_index app/routes/dolla-bills-[$].tsx /dolla-bills-$ app/routes/[[so-weird]].tsx /[so-weird] Folders for Organization Routes can also be folders with a route.tsx file inside defining the route module. The rest of the files in the folder will not become routes. This allows you to organize your code closer to the routes that use them instead of repeating the feature names across other folders. The files inside a folder have no meaning for the route paths, the route path is completely defined by the folder name Consider these routes: app/ ├── routes/ │ ├── _landing._index.tsx │ ├── _landing.about.tsx │ ├── _landing.tsx │ ├── app._index.tsx │ ├── app.projects.tsx │ ├── app.tsx │ └── app_.projects.$id.roadmap.tsx └── root.tsx Some, or all of them can be folders holding their own route module inside. app/ ├── routes/ │ ├── _landing._index/ │ │ ├── route.tsx │ │ └── scroll-experience.tsx │ ├── _landing.about/ │ │ ├── employee-profile-card.tsx │ │ ├── get-employee-data.server.ts │ │ ├── route.tsx │ │ └── team-photo.jpg │ ├── _landing/ │ │ ├── footer.tsx │ │ ├── header.tsx │ │ └── route.tsx │ ├── app._index/ │ │ ├── route.tsx │ │ └── stats.tsx │ ├── app.projects/ │ │ ├── get-projects.server.ts │ │ ├── project-buttons.tsx │ │ ├── project-card.tsx │ │ └── route.tsx │ ├── app/ │ │ ├── footer.tsx │ │ ├── primary-nav.tsx │ │ └── route.tsx │ ├── app_.projects.$id.roadmap/ │ │ ├── chart.tsx │ │ ├── route.tsx │ │ └── update-timeline.server.ts │ └── contact-us.tsx └── root.tsx Note that when you turn a route module into a folder, the route module becomes folder/route.tsx, all other modules in the folder will not become routes. For example: # these are the same route: app/routes/app.tsx app/routes/app/route.tsx # as are these app/routes/app._index.tsx app/routes/app._index/route.tsx Scaling Our general recommendation for scale is to make every route a folder and put the modules used exclusively by that route in the folder, then put the shared modules outside the routes folder elsewhere. This has a couple of benefits: Easy to identify shared modules, so tread lightly when changing them Easy to organize and refactor the modules for a specific route without creating \"file organization fatigue\" and cluttering up other parts of the app © 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,\\\"_1002\\\":-5,\\\"_1003\\\":-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\\\":1001},{\\\"_18\\\":204},\\\"docs/file-conventions/routes.md\\\",\\\"html\\\",\\\"\\u003ch1 id=\\\\\\\"route-file-naming\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#route-file-naming\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eRoute File Naming\\u003c/h1\\u003e\\\\n\\u003cp\\u003eWhile you can configure routes via \\u003ca href=\\\\\\\"./vite-config#routes\\\\\\\"\\u003ethe \\\\\\\"routes\\\\\\\" plugin option\\u003c/a\\u003e, most routes are created with this file system convention. Add a file, get a route.\\u003c/p\\u003e\\\\n\\u003cp\\u003ePlease note that you can use either \\u003ccode\\u003e.js\\u003c/code\\u003e, \\u003ccode\\u003e.jsx\\u003c/code\\u003e, \\u003ccode\\u003e.ts\\u003c/code\\u003e or \\u003ccode\\u003e.tsx\\u003c/code\\u003e file extensions. We'll stick with \\u003ccode\\u003e.tsx\\u003c/code\\u003e in the examples to avoid duplication.\\u003c/p\\u003e\\\\n\\u003cp\\u003e\\u003cdocs-info\\u003eDilum Sanjaya made \\u003ca href=\\\\\\\"https://interactive-remix-routing-v2.netlify.app/\\\\\\\"\\u003ean awesome visualization\\u003c/a\\u003e of how routes in the file system map to the URL in your app that might help you understand these conventions.\\u003c/docs-info\\u003e\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"disclaimer\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#disclaimer\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eDisclaimer\\u003c/h2\\u003e\\\\n\\u003cp\\u003eBefore we go too far into the Remix convention, though, we'd like to point out that file-based routing is an \\u003cstrong\\u003eincredibly\\u003c/strong\\u003e subjective idea. Some folks love the \\\\\\\"flat\\\\\\\" routes idea, some folks hate it and would prefer nesting routes in folders. Some folks simply hate file-based routing and would prefer to configure routes via JSON. Some folks would prefer to configure routes via JSX like they did in their React Router SPA's.\\u003c/p\\u003e\\\\n\\u003cp\\u003eThe point is, we are well aware of this and from the get-go, Remix has always given you a first-class way to opt-out via the \\u003ca href=\\\\\\\"./vite-config#routes\\\\\\\"\\u003e\\u003ccode\\u003eroutes\\u003c/code\\u003e\\u003c/a\\u003e/\\u003ca href=\\\\\\\"./vite-config#ignoredroutefiles\\\\\\\"\\u003e\\u003ccode\\u003eignoredRouteFiles\\u003c/code\\u003e\\u003c/a\\u003e and \\u003ca href=\\\\\\\"../discussion/routes#manual-route-configuration\\\\\\\"\\u003econfigure your routes manually\\u003c/a\\u003e. But, there has to be \\u003cem\\u003esome\\u003c/em\\u003e default so that folks can get up and running quickly and easily - and we think that the flat routes convention document below is a pretty good default that scales well for small-to-medium sized apps.\\u003c/p\\u003e\\\\n\\u003cp\\u003eLarge applications with hundreds or thousands of routes will \\u003cem\\u003ealways\\u003c/em\\u003e be a bit chaotic no matter what convention you use — and the idea is that via the \\u003ccode\\u003eroutes\\u003c/code\\u003e config, you get to build \\u003cem\\u003eexactly\\u003c/em\\u003e the convention that works best for your application/team. It would be quite literally impossible for Remix to have a default convention that made everyone happy. We'd much rather give you a fairly straightforward default and then let the community build any number of conventions you can pick and choose from.\\u003c/p\\u003e\\\\n\\u003cp\\u003eSo, before we dive into the details of the Remix default convention, here are some community alternatives you can check out if you decide that our default is not your cup of tea.\\u003c/p\\u003e\\\\n\\u003cul\\u003e\\\\n\\u003cli\\u003e\\u003ca href=\\\\\\\"https://github.com/kiliman/remix-flat-routes\\\\\\\"\\u003e\\u003ccode\\u003eremix-flat-routes\\u003c/code\\u003e\\u003c/a\\u003e - The Remix default is basically a simplified version of this package. The author has continued to iterate on and evolve this package, so if you generally like the \\\\\\\"flat routes\\\\\\\" idea but want a bit more power (including a hybrid approach of files and folders), definitely check this one out.\\u003c/li\\u003e\\\\n\\u003cli\\u003e\\u003ca href=\\\\\\\"https://github.com/jacobparis-insiders/remix-custom-routes\\\\\\\"\\u003e\\u003ccode\\u003eremix-custom-routes\\u003c/code\\u003e\\u003c/a\\u003e - If you want even more customization, this package lets you define that types of files should be treated as routes. This lets you go beyond the simple flat/nested concept and do something such as \\u003cem\\u003e\\\\\\\"any file with an extension of \\u003ccode\\u003e.route.tsx\\u003c/code\\u003e is a route\\\\\\\"\\u003c/em\\u003e.\\u003c/li\\u003e\\\\n\\u003cli\\u003e\\u003ca href=\\\\\\\"https://github.com/brophdawg11/remix-json-routes\\\\\\\"\\u003e\\u003ccode\\u003eremix-json-routes\\u003c/code\\u003e\\u003c/a\\u003e - If you just want to specify your routes via a config file, this is your jam — provide Remix a JSON object with your routes and skip the flat/nested concept entirely. There's even a JSX option in there too.\\u003c/li\\u003e\\\\n\\u003c/ul\\u003e\\\\n\\u003ch2 id=\\\\\\\"root-route\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#root-route\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eRoot Route\\u003c/h2\\u003e\\\\n\\u003cpre\\u003e\\u003ccode class=\\\\\\\"language-text\\\\\\\"\\u003eapp/\\\\n├── routes/\\\\n└── root.tsx\\\\n\\u003c/code\\u003e\\u003c/pre\\u003e\\\\n\\u003cp\\u003eThe file in \\u003ccode\\u003eapp/root.tsx\\u003c/code\\u003e is your root layout, or \\\\\\\"root route\\\\\\\" (very sorry for those of you who pronounce those words the same way!). It works just like all other routes, so you can export a \\u003ca href=\\\\\\\"../route/loader\\\\\\\"\\u003e\\u003ccode\\u003eloader\\u003c/code\\u003e\\u003c/a\\u003e, \\u003ca href=\\\\\\\"../route/action\\\\\\\"\\u003e\\u003ccode\\u003eaction\\u003c/code\\u003e\\u003c/a\\u003e, etc.\\u003c/p\\u003e\\\\n\\u003cp\\u003eThe root route typically looks something like this. It serves as the root layout of the entire app, all other routes will render inside the \\u003ca href=\\\\\\\"../components/outlet\\\\\\\"\\u003e\\u003ccode\\u003e\\u0026#x3C;Outlet /\\u003e\\u003c/code\\u003e\\u003c/a\\u003e.\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\" 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 {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eLinks\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eMeta\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eOutlet\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eScripts\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eScrollRestoration\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e} \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/react\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003edefault\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003efunction\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eRoot\\u003c/span\\u003e() {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ehtml\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003elang\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003een\\u003c/span\\u003e\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ehead\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eLinks\\u003c/span\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eMeta\\u003c/span\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ehead\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eOutlet\\u003c/span\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eScrollRestoration\\u003c/span\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eScripts\\u003c/span\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"20\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"21\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ehtml\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"22\\\\\\\"\\u003e );\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"23\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003ch2 id=\\\\\\\"basic-routes\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#basic-routes\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eBasic Routes\\u003c/h2\\u003e\\\\n\\u003cp\\u003eAny JavaScript or TypeScript files in the \\u003ccode\\u003eapp/routes\\u003c/code\\u003e directory will become routes in your application. The filename maps to the route's URL pathname, except for \\u003ccode\\u003e_index.tsx\\u003c/code\\u003e which is the \\u003ca href=\\\\\\\"../discussion/routes#index-routes\\\\\\\"\\u003eindex route\\u003c/a\\u003e for the \\u003ca href=\\\\\\\"#root-route\\\\\\\"\\u003eroot route\\u003c/a\\u003e.\\u003c/p\\u003e\\\\n\\u003cpre\\u003e\\u003ccode class=\\\\\\\"language-text\\\\\\\"\\u003eapp/\\\\n├── routes/\\\\n│ ├── _index.tsx\\\\n│ └── about.tsx\\\\n└── root.tsx\\\\n\\u003c/code\\u003e\\u003c/pre\\u003e\\\\n\\u003ctable\\u003e\\\\n\\u003cthead\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003cth\\u003eURL\\u003c/th\\u003e\\\\n\\u003cth\\u003eMatched Routes\\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\\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\\u003c/tr\\u003e\\\\n\\u003c/tbody\\u003e\\\\n\\u003c/table\\u003e\\\\n\\u003cp\\u003eNote that these routes will be rendered in the outlet of \\u003ccode\\u003eapp/root.tsx\\u003c/code\\u003e because of \\u003ca href=\\\\\\\"../discussion/routes#what-is-nested-routing\\\\\\\"\\u003enested routing\\u003c/a\\u003e.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"dot-delimiters\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#dot-delimiters\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eDot Delimiters\\u003c/h2\\u003e\\\\n\\u003cp\\u003eAdding a \\u003ccode\\u003e.\\u003c/code\\u003e to a route filename will create a \\u003ccode\\u003e/\\u003c/code\\u003e in the URL.\\u003c/p\\u003e\\\\n\\u003cpre\\u003e\\u003ccode class=\\\\\\\"language-text\\\\\\\"\\u003e app/\\\\n├── routes/\\\\n│ ├── _index.tsx\\\\n│ ├── about.tsx\\\\n│ ├── concerts.trending.tsx\\\\n│ ├── concerts.salt-lake-city.tsx\\\\n│ └── concerts.san-diego.tsx\\\\n└── root.tsx\\\\n\\u003c/code\\u003e\\u003c/pre\\u003e\\\\n\\u003ctable\\u003e\\\\n\\u003cthead\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003cth\\u003eURL\\u003c/th\\u003e\\\\n\\u003cth\\u003eMatched Route\\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\\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\\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\\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.salt-lake-city.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e/concerts/san-diego\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/concerts.san-diego.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003c/tbody\\u003e\\\\n\\u003c/table\\u003e\\\\n\\u003cp\\u003eThe dot delimiter also creates nesting, see the \\u003ca href=\\\\\\\"#nested-routes\\\\\\\"\\u003enesting section\\u003c/a\\u003e for more information.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"dynamic-segments\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#dynamic-segments\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eDynamic Segments\\u003c/h2\\u003e\\\\n\\u003cp\\u003eUsually your URLs aren't static but data-driven. Dynamic segments allow you to match segments of the URL and use that value in your code. You create them with the \\u003ccode\\u003e$\\u003c/code\\u003e prefix.\\u003c/p\\u003e\\\\n\\u003cpre\\u003e\\u003ccode class=\\\\\\\"language-text\\\\\\\"\\u003e app/\\\\n├── routes/\\\\n│ ├── _index.tsx\\\\n│ ├── about.tsx\\\\n│ ├── concerts.$city.tsx\\\\n│ └── concerts.trending.tsx\\\\n└── root.tsx\\\\n\\u003c/code\\u003e\\u003c/pre\\u003e\\\\n\\u003ctable\\u003e\\\\n\\u003cthead\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003cth\\u003eURL\\u003c/th\\u003e\\\\n\\u003cth\\u003eMatched Route\\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\\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\\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\\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\\u003c/tr\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e/concerts/san-diego\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/concerts.$city.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003c/tbody\\u003e\\\\n\\u003c/table\\u003e\\\\n\\u003cp\\u003eRemix will parse the value from the URL and pass it to various APIs. We call these values \\\\\\\"URL Parameters\\\\\\\". The most useful places to access the URL params are in \\u003ca href=\\\\\\\"../route/loader\\\\\\\"\\u003eloaders\\u003c/a\\u003e and \\u003ca href=\\\\\\\"../route/action\\\\\\\"\\u003eactions\\u003c/a\\u003e.\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003easync\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003efunction\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eloader\\u003c/span\\u003e({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e}\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eLoaderFunctionArgs\\u003c/span\\u003e) {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efakeDb\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003egetAllConcertsForCity\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ecity\\u003c/span\\u003e);\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eYou'll note the property name on the \\u003ccode\\u003eparams\\u003c/code\\u003e object maps directly to the name of your file: \\u003ccode\\u003e$city.tsx\\u003c/code\\u003e becomes \\u003ccode\\u003eparams.city\\u003c/code\\u003e.\\u003c/p\\u003e\\\\n\\u003cp\\u003eRoutes can have multiple dynamic segments, like \\u003ccode\\u003econcerts.$city.$date\\u003c/code\\u003e, both are accessed on the params object by name:\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003easync\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003efunction\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eloader\\u003c/span\\u003e({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e}\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eLoaderFunctionArgs\\u003c/span\\u003e) {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efake\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003edb\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003egetConcerts\\u003c/span\\u003e({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e date: \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003edate\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e city: \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ecity\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e });\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eSee the \\u003ca href=\\\\\\\"../discussion/routes\\\\\\\"\\u003erouting guide\\u003c/a\\u003e for more information.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"nested-routes\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#nested-routes\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eNested Routes\\u003c/h2\\u003e\\\\n\\u003cp\\u003eNested Routing is the general idea of coupling segments of the URL to component hierarchy and data. You can read more about it in the \\u003ca href=\\\\\\\"../discussion/routes#what-is-nested-routing\\\\\\\"\\u003eRouting Guide\\u003c/a\\u003e.\\u003c/p\\u003e\\\\n\\u003cp\\u003eYou create nested routes with \\u003ca href=\\\\\\\"#dot-delimiters\\\\\\\"\\u003edot delimiters\\u003c/a\\u003e. If the filename before the \\u003ccode\\u003e.\\u003c/code\\u003e matches another route filename, it automatically becomes a child route to the matching parent. Consider these routes:\\u003c/p\\u003e\\\\n\\u003cpre\\u003e\\u003ccode class=\\\\\\\"language-text\\\\\\\"\\u003e app/\\\\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 and render inside the parent route's \\u003ca href=\\\\\\\"../components/outlet\\\\\\\"\\u003eoutlet_component\\u003c/a\\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\\u003cp\\u003eNote you typically want to add an index route when you add nested routes so that something renders inside the parent's outlet when users visit the parent URL directly.\\u003c/p\\u003e\\\\n\\u003cp\\u003eFor example, if the URL is \\u003ccode\\u003e/concerts/salt-lake-city\\u003c/code\\u003e then the UI hierarchy will look like this:\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eRoot\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eConcerts\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eCity\\u003c/span\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eConcerts\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eRoot\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003ch2 id=\\\\\\\"nested-urls-without-layout-nesting\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#nested-urls-without-layout-nesting\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eNested URLs without Layout Nesting\\u003c/h2\\u003e\\\\n\\u003cp\\u003eSometimes you want the URL to be nested, but you don't want the automatic layout nesting. You can opt out of nesting with a trailing underscore on the parent segment:\\u003c/p\\u003e\\\\n\\u003cpre\\u003e\\u003ccode class=\\\\\\\"language-text\\\\\\\"\\u003e app/\\\\n├── routes/\\\\n│ ├── _index.tsx\\\\n│ ├── about.tsx\\\\n│ ├── concerts.$city.tsx\\\\n│ ├── concerts.trending.tsx\\\\n│ ├── concerts.tsx\\\\n│ └── concerts_.mine.tsx\\\\n└── root.tsx\\\\n\\u003c/code\\u003e\\u003c/pre\\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/mine\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/concerts_.mine.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/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\\u003cp\\u003eNote that \\u003ccode\\u003e/concerts/mine\\u003c/code\\u003e does not nest with \\u003ccode\\u003eapp/routes/concerts.tsx\\u003c/code\\u003e anymore, but \\u003ccode\\u003eapp/root.tsx\\u003c/code\\u003e. The \\u003ccode\\u003etrailing_\\u003c/code\\u003e underscore creates a path segment, but it does not create layout nesting.\\u003c/p\\u003e\\\\n\\u003cp\\u003eThink of the \\u003ccode\\u003etrailing_\\u003c/code\\u003e underscore as the long bit at the end of your parent's signature, writing you out of the will, removing the segment that follows from the layout nesting.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"nested-layouts-without-nested-urls\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#nested-layouts-without-nested-urls\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eNested Layouts without Nested URLs\\u003c/h2\\u003e\\\\n\\u003cp\\u003eWe call these \\u003ca name=\\\\\\\"pathless-routes\\\\\\\"\\u003e\\u003cb\\u003ePathless Routes\\u003c/b\\u003e\\u003c/a\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eSometimes you want to share a layout with a group of routes without adding any path segments to the URL. A common example is a set of authentication routes that have a different header/footer than the public pages or the logged-in-app experience. You can do this with a \\u003ccode\\u003e_leading\\u003c/code\\u003e underscore.\\u003c/p\\u003e\\\\n\\u003cpre\\u003e\\u003ccode class=\\\\\\\"language-text\\\\\\\"\\u003e app/\\\\n├── routes/\\\\n│ ├── _auth.login.tsx\\\\n│ ├── _auth.register.tsx\\\\n│ ├── _auth.tsx\\\\n│ ├── _index.tsx\\\\n│ ├── concerts.$city.tsx\\\\n│ └── concerts.tsx\\\\n└── root.tsx\\\\n\\u003c/code\\u003e\\u003c/pre\\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/login\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/_auth.login.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/_auth.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e/register\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/_auth.register.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/_auth.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.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/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\\u003cp\\u003eThink of the \\u003ccode\\u003e_leading\\u003c/code\\u003e underscore as a blanket you're pulling over the filename, hiding the filename from the URL.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"optional-segments\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#optional-segments\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eOptional Segments\\u003c/h2\\u003e\\\\n\\u003cp\\u003eWrapping a route segment in parentheses will make the segment optional.\\u003c/p\\u003e\\\\n\\u003cpre\\u003e\\u003ccode class=\\\\\\\"language-text\\\\\\\"\\u003e app/\\\\n├── routes/\\\\n│ ├── ($lang)._index.tsx\\\\n│ ├── ($lang).$productId.tsx\\\\n│ └── ($lang).categories.tsx\\\\n└── root.tsx\\\\n\\u003c/code\\u003e\\u003c/pre\\u003e\\\\n\\u003ctable\\u003e\\\\n\\u003cthead\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003cth\\u003eURL\\u003c/th\\u003e\\\\n\\u003cth\\u003eMatched Route\\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/($lang)._index.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e/categories\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/($lang).categories.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e/en/categories\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/($lang).categories.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e/fr/categories\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/($lang).categories.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e/american-flag-speedo\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/($lang)._index.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e/en/american-flag-speedo\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/($lang).$productId.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e/fr/american-flag-speedo\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/($lang).$productId.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003c/tbody\\u003e\\\\n\\u003c/table\\u003e\\\\n\\u003cp\\u003eYou may wonder why \\u003ccode\\u003e/american-flag-speedo\\u003c/code\\u003e is matching the \\u003ccode\\u003e($lang)._index.tsx\\u003c/code\\u003e route instead of \\u003ccode\\u003e($lang).$productId.tsx\\u003c/code\\u003e. This is because when you have an optional dynamic param segment followed by another dynamic param, Remix cannot reliably determine if a single-segment URL such as \\u003ccode\\u003e/american-flag-speedo\\u003c/code\\u003e should match \\u003ccode\\u003e/:lang\\u003c/code\\u003e \\u003ccode\\u003e/:productId\\u003c/code\\u003e. Optional segments match eagerly and thus it will match \\u003ccode\\u003e/:lang\\u003c/code\\u003e. If you have this type of setup, it's recommended to look at \\u003ccode\\u003eparams.lang\\u003c/code\\u003e in the \\u003ccode\\u003e($lang)._index.tsx\\u003c/code\\u003e loader and redirect to \\u003ccode\\u003e/:lang/american-flag-speedo\\u003c/code\\u003e for the current/default language if \\u003ccode\\u003eparams.lang\\u003c/code\\u003e is not a valid language code.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"splat-routes\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#splat-routes\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eSplat Routes\\u003c/h2\\u003e\\\\n\\u003cp\\u003eWhile \\u003ca href=\\\\\\\"#dynamic-segments\\\\\\\"\\u003edynamic segments\\u003c/a\\u003e match a single path segment (the stuff between two \\u003ccode\\u003e/\\u003c/code\\u003e in a URL), a splat route will match the rest of a URL, including the slashes.\\u003c/p\\u003e\\\\n\\u003cpre\\u003e\\u003ccode class=\\\\\\\"language-text\\\\\\\"\\u003e app/\\\\n├── routes/\\\\n│ ├── _index.tsx\\\\n│ ├── $.tsx\\\\n│ ├── about.tsx\\\\n│ └── files.$.tsx\\\\n└── root.tsx\\\\n\\u003c/code\\u003e\\u003c/pre\\u003e\\\\n\\u003ctable\\u003e\\\\n\\u003cthead\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003cth\\u003eURL\\u003c/th\\u003e\\\\n\\u003cth\\u003eMatched Route\\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\\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\\u003c/tr\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e/beef/and/cheese\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/$.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e/files\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/files.$.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e/files/talks/remix-conf_old.pdf\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/files.$.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e/files/talks/remix-conf_final.pdf\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/files.$.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e/files/talks/remix-conf-FINAL-MAY_2022.pdf\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/files.$.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003c/tbody\\u003e\\\\n\\u003c/table\\u003e\\\\n\\u003cp\\u003eSimilar to dynamic route parameters, you can access the value of the matched path on the splat route's \\u003ccode\\u003eparams\\u003c/code\\u003e with the \\u003ccode\\u003e\\\\\\\"*\\\\\\\"\\u003c/code\\u003e key.\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/routes/files.$.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/routes/files.$.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003easync\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003efunction\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eloader\\u003c/span\\u003e({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e}\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eLoaderFunctionArgs\\u003c/span\\u003e) {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efilePath\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e[\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e*\\u003c/span\\u003e\\\\\\\"];\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efake\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003egetFileInfo\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efilePath\\u003c/span\\u003e);\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003ch2 id=\\\\\\\"escaping-special-characters\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#escaping-special-characters\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eEscaping Special Characters\\u003c/h2\\u003e\\\\n\\u003cp\\u003eIf you want one of the special characters Remix uses for these route conventions to actually be a part of the URL, you can escape the conventions with \\u003ccode\\u003e[]\\u003c/code\\u003e characters.\\u003c/p\\u003e\\\\n\\u003ctable\\u003e\\\\n\\u003cthead\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003cth\\u003eFilename\\u003c/th\\u003e\\\\n\\u003cth\\u003eURL\\u003c/th\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003c/thead\\u003e\\\\n\\u003ctbody\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/sitemap[.]xml.tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e/sitemap.xml\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/[sitemap.xml].tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e/sitemap.xml\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/weird-url.[_index].tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e/weird-url/_index\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/dolla-bills-[$].tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e/dolla-bills-$\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003eapp/routes/[[so-weird]].tsx\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e/[so-weird]\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003c/tbody\\u003e\\\\n\\u003c/table\\u003e\\\\n\\u003ch2 id=\\\\\\\"folders-for-organization\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#folders-for-organization\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eFolders for Organization\\u003c/h2\\u003e\\\\n\\u003cp\\u003eRoutes can also be folders with a \\u003ccode\\u003eroute.tsx\\u003c/code\\u003e file inside defining the route module. The rest of the files in the folder will not become routes. This allows you to organize your code closer to the routes that use them instead of repeating the feature names across other folders.\\u003c/p\\u003e\\\\n\\u003cp\\u003e\\u003cdocs-info\\u003eThe files inside a folder have no meaning for the route paths, the route path is completely defined by the folder name\\u003c/docs-info\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eConsider these routes:\\u003c/p\\u003e\\\\n\\u003cpre\\u003e\\u003ccode class=\\\\\\\"language-text\\\\\\\"\\u003e app/\\\\n├── routes/\\\\n│ ├── _landing._index.tsx\\\\n│ ├── _landing.about.tsx\\\\n│ ├── _landing.tsx\\\\n│ ├── app._index.tsx\\\\n│ ├── app.projects.tsx\\\\n│ ├── app.tsx\\\\n│ └── app_.projects.$id.roadmap.tsx\\\\n└── root.tsx\\\\n\\u003c/code\\u003e\\u003c/pre\\u003e\\\\n\\u003cp\\u003eSome, or all of them can be folders holding their own \\u003ccode\\u003eroute\\u003c/code\\u003e module inside.\\u003c/p\\u003e\\\\n\\u003cpre\\u003e\\u003ccode class=\\\\\\\"language-text\\\\\\\"\\u003eapp/\\\\n├── routes/\\\\n│ ├── _landing._index/\\\\n│ │ ├── route.tsx\\\\n│ │ └── scroll-experience.tsx\\\\n│ ├── _landing.about/\\\\n│ │ ├── employee-profile-card.tsx\\\\n│ │ ├── get-employee-data.server.ts\\\\n│ │ ├── route.tsx\\\\n│ │ └── team-photo.jpg\\\\n│ ├── _landing/\\\\n│ │ ├── footer.tsx\\\\n│ │ ├── header.tsx\\\\n│ │ └── route.tsx\\\\n│ ├── app._index/\\\\n│ │ ├── route.tsx\\\\n│ │ └── stats.tsx\\\\n│ ├── app.projects/\\\\n│ │ ├── get-projects.server.ts\\\\n│ │ ├── project-buttons.tsx\\\\n│ │ ├── project-card.tsx\\\\n│ │ └── route.tsx\\\\n│ ├── app/\\\\n│ │ ├── footer.tsx\\\\n│ │ ├── primary-nav.tsx\\\\n│ │ └── route.tsx\\\\n│ ├── app_.projects.$id.roadmap/\\\\n│ │ ├── chart.tsx\\\\n│ │ ├── route.tsx\\\\n│ │ └── update-timeline.server.ts\\\\n│ └── contact-us.tsx\\\\n└── root.tsx\\\\n\\u003c/code\\u003e\\u003c/pre\\u003e\\\\n\\u003cp\\u003eNote that when you turn a route module into a folder, the route module becomes \\u003ccode\\u003efolder/route.tsx\\u003c/code\\u003e, all other modules in the folder will not become routes. For example:\\u003c/p\\u003e\\\\n\\u003cpre\\u003e\\u003ccode\\u003e# these are the same route:\\\\napp/routes/app.tsx\\\\napp/routes/app/route.tsx\\\\n\\\\n# as are these\\\\napp/routes/app._index.tsx\\\\napp/routes/app._index/route.tsx\\\\n\\u003c/code\\u003e\\u003c/pre\\u003e\\\\n\\u003ch2 id=\\\\\\\"scaling\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#scaling\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eScaling\\u003c/h2\\u003e\\\\n\\u003cp\\u003eOur general recommendation for scale is to make every route a folder and put the modules used exclusively by that route in the folder, then put the shared modules outside the \\u003ccode\\u003eroutes\\u003c/code\\u003e folder elsewhere. This has a couple of benefits:\\u003c/p\\u003e\\\\n\\u003cul\\u003e\\\\n\\u003cli\\u003eEasy to identify shared modules, so tread lightly when changing them\\u003c/li\\u003e\\\\n\\u003cli\\u003eEasy to organize and refactor the modules for a specific route without creating \\\\\\\"file organization fatigue\\\\\\\" and cluttering up other parts of the app\\u003c/li\\u003e\\\\n\\u003c/ul\\u003e\\\",\\\"docs/file-conventions/routes\\\",\\\"headings\\\",[960,965,968,971,974,977,980,983,986,989,992,995,998],{\\\"_961\\\":962,\\\"_955\\\":963,\\\"_24\\\":964},\\\"headingLevel\\\",\\\"h2\\\",\\\"Disclaimer\\\",\\\"disclaimer\\\",{\\\"_961\\\":962,\\\"_955\\\":966,\\\"_24\\\":967},\\\"Root Route\\\",\\\"root-route\\\",{\\\"_961\\\":962,\\\"_955\\\":969,\\\"_24\\\":970},\\\"Basic Routes\\\",\\\"basic-routes\\\",{\\\"_961\\\":962,\\\"_955\\\":972,\\\"_24\\\":973},\\\"Dot Delimiters\\\",\\\"dot-delimiters\\\",{\\\"_961\\\":962,\\\"_955\\\":975,\\\"_24\\\":976},\\\"Dynamic Segments\\\",\\\"dynamic-segments\\\",{\\\"_961\\\":962,\\\"_955\\\":978,\\\"_24\\\":979},\\\"Nested Routes\\\",\\\"nested-routes\\\",{\\\"_961\\\":962,\\\"_955\\\":981,\\\"_24\\\":982},\\\"Nested URLs without Layout Nesting\\\",\\\"nested-urls-without-layout-nesting\\\",{\\\"_961\\\":962,\\\"_955\\\":984,\\\"_24\\\":985},\\\"Nested Layouts without Nested URLs\\\",\\\"nested-layouts-without-nested-urls\\\",{\\\"_961\\\":962,\\\"_955\\\":987,\\\"_24\\\":988},\\\"Optional Segments\\\",\\\"optional-segments\\\",{\\\"_961\\\":962,\\\"_955\\\":990,\\\"_24\\\":991},\\\"Splat Routes\\\",\\\"splat-routes\\\",{\\\"_961\\\":962,\\\"_955\\\":993,\\\"_24\\\":994},\\\"Escaping Special Characters\\\",\\\"escaping-special-characters\\\",{\\\"_961\\\":962,\\\"_955\\\":996,\\\"_24\\\":997},\\\"Folders for Organization\\\",\\\"folders-for-organization\\\",{\\\"_961\\\":962,\\\"_955\\\":999,\\\"_24\\\":1000},\\\"Scaling\\\",\\\"scaling\\\",[],\\\"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/file-conventions/routes",
|
|
"metadata": {
|
|
"description": "",
|
|
"headings": [
|
|
"Route File Naming",
|
|
"Disclaimer",
|
|
"Root Route",
|
|
"Basic Routes",
|
|
"Dot Delimiters",
|
|
"Dynamic Segments",
|
|
"Nested Routes",
|
|
"Nested URLs without Layout Nesting",
|
|
"Nested Layouts without Nested URLs",
|
|
"Optional Segments",
|
|
"Splat Routes",
|
|
"Escaping Special Characters",
|
|
"Folders for Organization",
|
|
"Scaling"
|
|
],
|
|
"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/file-conventions/routes/#disclaimer",
|
|
"/docs/file-conventions/routes/#root-route",
|
|
"/docs/file-conventions/routes/#basic-routes",
|
|
"/docs/file-conventions/routes/#dot-delimiters",
|
|
"/docs/file-conventions/routes/#dynamic-segments",
|
|
"/docs/file-conventions/routes/#nested-routes",
|
|
"/docs/file-conventions/routes/#nested-urls-without-layout-nesting",
|
|
"/docs/file-conventions/routes/#nested-layouts-without-nested-urls",
|
|
"/docs/file-conventions/routes/#optional-segments",
|
|
"/docs/file-conventions/routes/#splat-routes",
|
|
"/docs/file-conventions/routes/#escaping-special-characters",
|
|
"/docs/file-conventions/routes/#folders-for-organization",
|
|
"/docs/file-conventions/routes/#scaling",
|
|
"./vite-config#routes",
|
|
"https://interactive-remix-routing-v2.netlify.app/",
|
|
"./vite-config#ignoredroutefiles",
|
|
"../discussion/routes#manual-route-configuration",
|
|
"https://github.com/kiliman/remix-flat-routes",
|
|
"https://github.com/jacobparis-insiders/remix-custom-routes",
|
|
"https://github.com/brophdawg11/remix-json-routes",
|
|
"../route/loader",
|
|
"../route/action",
|
|
"../components/outlet",
|
|
"../discussion/routes#index-routes",
|
|
"../discussion/routes#what-is-nested-routing",
|
|
"../discussion/routes",
|
|
"https://remix.run",
|
|
"https://opensource.org/licenses/MIT",
|
|
"https://github.com/remix-run/remix-v2-website/edit/main/data/docs/file-conventions/routes.md"
|
|
]
|
|
},
|
|
"hash": "d60df875187116a6a5d40fa071740826d3ba481e548766bb6c35f308ec3f48af",
|
|
"timestamp": "2026-02-23T11:36:17.295236124+01:00"
|
|
} |