mirror of
https://github.com/Dvorinka/Devour.git
synced 2026-06-04 20:43:05 +00:00
278 lines
484 KiB
JSON
278 lines
484 KiB
JSON
{
|
||
"id": "95221a927aafce7d4682355f",
|
||
"source": "remix:does",
|
||
"type": "html",
|
||
"title": "Tutorial (30m) | Remix",
|
||
"content": "DocsBlogResourcesReact Router v7 has been released. View the docsDocsBlogResourcesView code on GitHubChat on DiscordReact Router v7 has been released. View the docsTutorial (30m)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 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 pageSetupThe Root RouteAdding Stylesheets with linksThe Contact Route UINested Routes and OutletsClient Side RoutingLoading DataType InferenceURL Params in LoadersValidating Params and Throwing ResponsesData MutationsCreating ContactsUpdating DataUpdating Contacts with FormDataMutation DiscussionRedirecting new records to the edit pageActive Link StylingGlobal Pending UIDeleting RecordsIndex RoutesCancel ButtonURLSearchParams and GET SubmissionsSynchronizing URLs to Form StateSubmitting Form's onChangeAdding Search SpinnerManaging the History StackForms Without NavigationOptimistic UIOn this pageSetupThe Root RouteAdding Stylesheets with linksThe Contact Route UINested Routes and OutletsClient Side RoutingLoading DataType InferenceURL Params in LoadersValidating Params and Throwing ResponsesData MutationsCreating ContactsUpdating DataUpdating Contacts with FormDataMutation DiscussionRedirecting new records to the edit pageActive Link StylingGlobal Pending UIDeleting RecordsIndex RoutesCancel ButtonURLSearchParams and GET SubmissionsSynchronizing URLs to Form StateSubmitting Form's onChangeAdding Search SpinnerManaging the History StackForms Without NavigationOptimistic UIRemix Tutorial Just getting started with Remix? The latest version of Remix is now React Router v7. If you want to use the latest framework features, you can follow the same tutorial from the React Router docs. We'll be building a small, but feature-rich app that lets you keep track of your contacts. There's no database or other \"production ready\" things, so we can stay focused on Remix. We expect it to take about 30 m if you're following along, otherwise it's a quick read. 👉 Every time you see this, it means you need to do something in the app! The rest is just there for your information and deeper understanding. Let's get to it. Setup 👉 Generate a basic template npx create-remix@latest --template remix-run/remix/templates/remix-tutorial This uses a pretty bare-bones template but includes our CSS and data model, so we can focus on Remix. The Quick Start can familiarize you with the basic setup of a Remix project if you'd like to learn more. 👉 Start the app # cd into the app directory cd {wherever you put the app} # install dependencies if you haven't already npm install # start the server npm run dev You should be able to open up http://localhost:5173 and see an unstyled screen that looks like this: The Root Route Note the file at app/root.tsx. This is what we call the \"Root Route\". It's the first component in the UI that renders, so it typically contains the global layout for the page. Expand here to see the root component code import { Form, Links, Meta, Scripts, ScrollRestoration, } from \"@remix-run/react\"; export default function App() { return ( \u003chtml lang=\"en\"\u003e \u003chead\u003e \u003cmeta charSet=\"utf-8\" /\u003e \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\" /\u003e \u003cMeta /\u003e \u003cLinks /\u003e \u003c/head\u003e \u003cbody\u003e \u003cdiv id=\"sidebar\"\u003e \u003ch1\u003eRemix Contacts\u003c/h1\u003e \u003cdiv\u003e \u003cForm id=\"search-form\" role=\"search\"\u003e \u003cinput aria-label=\"Search contacts\" id=\"q\" name=\"q\" placeholder=\"Search\" type=\"search\" /\u003e \u003cdiv aria-hidden hidden={true} id=\"search-spinner\" /\u003e \u003c/Form\u003e \u003cForm method=\"post\"\u003e \u003cbutton type=\"submit\"\u003eNew\u003c/button\u003e \u003c/Form\u003e \u003c/div\u003e \u003cnav\u003e \u003cul\u003e \u003cli\u003e \u003ca href={`/contacts/1`}\u003eYour Name\u003c/a\u003e \u003c/li\u003e \u003cli\u003e \u003ca href={`/contacts/2`}\u003eYour Friend\u003c/a\u003e \u003c/li\u003e \u003c/ul\u003e \u003c/nav\u003e \u003c/div\u003e \u003cScrollRestoration /\u003e \u003cScripts /\u003e \u003c/body\u003e \u003c/html\u003e ); } Adding Stylesheets with links While there are multiple ways to style your Remix app, we're going to use a plain stylesheet that's already been written to keep things focused on Remix. You can import CSS files directly into JavaScript modules. Vite will fingerprint the asset, save it to your build's client directory, and provide your module with the publicly accessible href. 👉 Import the app styles import type { LinksFunction } from \"@remix-run/node\"; // existing imports import appStylesHref from \"./app.css?url\"; export const links: LinksFunction = () =\u003e [ { rel: \"stylesheet\", href: appStylesHref }, ]; Every route can export a links function. They will be collected and rendered into the \u003cLinks /\u003e component we rendered in app/root.tsx. The app should look something like this now. It sure is nice having a designer who can also write the CSS, isn't it? (Thank you, Jim 🙏). The Contact Route UI If you click on one of the sidebar items, you'll get the default 404 page. Let's create a route that matches the url /contacts/1. 👉 Create the app/routes directory and contact route module mkdir app/routes touch app/routes/contacts.\\$contactId.tsx In the Remix route file convention, . will create a / in the URL and $ makes a segment dynamic. We just created a route that will match URLs that look like this: /contacts/123 /contacts/abc 👉 Add the contact component UI It's just a bunch of elements, feel free to copy/paste. import { Form } from \"@remix-run/react\"; import type { FunctionComponent } from \"react\"; import type { ContactRecord } from \"../data\"; export default function Contact() { const contact = { first: \"Your\", last: \"Name\", avatar: \"https://placecats.com/200/200\", twitter: \"your_handle\", notes: \"Some notes\", favorite: true, }; return ( \u003cdiv id=\"contact\"\u003e \u003cdiv\u003e \u003cimg alt={`${contact.first} ${contact.last} avatar`} key={contact.avatar} src={contact.avatar} /\u003e \u003c/div\u003e \u003cdiv\u003e \u003ch1\u003e {contact.first || contact.last ? ( \u003c\u003e {contact.first} {contact.last} \u003c/\u003e ) : ( \u003ci\u003eNo Name\u003c/i\u003e )}{\" \"} \u003cFavorite contact={contact} /\u003e \u003c/h1\u003e {contact.twitter ? ( \u003cp\u003e \u003ca href={`https://twitter.com/${contact.twitter}`} \u003e {contact.twitter} \u003c/a\u003e \u003c/p\u003e ) : null} {contact.notes ? \u003cp\u003e{contact.notes}\u003c/p\u003e : null} \u003cdiv\u003e \u003cForm action=\"edit\"\u003e \u003cbutton type=\"submit\"\u003eEdit\u003c/button\u003e \u003c/Form\u003e \u003cForm action=\"destroy\" method=\"post\" onSubmit={(event) =\u003e { const response = confirm( \"Please confirm you want to delete this record.\" ); if (!response) { event.preventDefault(); } }} \u003e \u003cbutton type=\"submit\"\u003eDelete\u003c/button\u003e \u003c/Form\u003e \u003c/div\u003e \u003c/div\u003e \u003c/div\u003e ); } const Favorite: FunctionComponent\u003c{ contact: Pick\u003cContactRecord, \"favorite\"\u003e; }\u003e = ({ contact }) =\u003e { const favorite = contact.favorite; return ( \u003cForm method=\"post\"\u003e \u003cbutton aria-label={ favorite ? \"Remove from favorites\" : \"Add to favorites\" } name=\"favorite\" value={favorite ? \"false\" : \"true\"} \u003e {favorite ? \"★\" : \"☆\"} \u003c/button\u003e \u003c/Form\u003e ); }; Now if we click one of the links or visit /contacts/1 we get ... nothing new? Nested Routes and Outlets Since Remix is built on top of React Router, it supports nested routing. In order for child routes to render inside parent layouts, we need to render an Outlet in the parent. Let's fix it, open up app/root.tsx and render an outlet inside. 👉 Render an \u003cOutlet /\u003e // existing imports import { Form, Links, Meta, Outlet, Scripts, ScrollRestoration, } from \"@remix-run/react\"; // existing imports \u0026 code export default function App() { return ( \u003chtml lang=\"en\"\u003e {/* other elements */} \u003cbody\u003e \u003cdiv id=\"sidebar\"\u003e{/* other elements */}\u003c/div\u003e \u003cdiv id=\"detail\"\u003e \u003cOutlet /\u003e \u003c/div\u003e {/* other elements */} \u003c/body\u003e \u003c/html\u003e ); } Now the child route should be rendered through the outlet. Client Side Routing You may or may not have noticed, but when we click the links in the sidebar, the browser is doing a full document request for the next URL instead of client side routing. Client side routing allows our app to update the URL without requesting another document from the server. Instead, the app can immediately render a new UI. Let's make it happen with \u003cLink\u003e. 👉 Change the sidebar \u003ca href\u003e to \u003cLink to\u003e // existing imports import { Form, Link, Links, Meta, Outlet, Scripts, ScrollRestoration, } from \"@remix-run/react\"; // existing imports and exports export default function App() { return ( \u003chtml lang=\"en\"\u003e {/* other elements */} \u003cbody\u003e \u003cdiv id=\"sidebar\"\u003e {/* other elements */} \u003cnav\u003e \u003cul\u003e \u003cli\u003e \u003cLink to={`/contacts/1`}\u003eYour Name\u003c/Link\u003e \u003c/li\u003e \u003cli\u003e \u003cLink to={`/contacts/2`}\u003eYour Friend\u003c/Link\u003e \u003c/li\u003e \u003c/ul\u003e \u003c/nav\u003e \u003c/div\u003e {/* other elements */} \u003c/body\u003e \u003c/html\u003e ); } You can open the network tab in the browser devtools to see that it's not requesting documents anymore. Loading Data URL segments, layouts, and data are more often than not coupled (tripled?) together. We can see it in this app already: URL Segment Component Data / \u003cRoot\u003e list of contacts contacts/:contactId \u003cContact\u003e individual contact Because of this natural coupling, Remix has data conventions to get data into your route components easily. There are two APIs we'll be using to load data, loader and useLoaderData. First we'll create and export a loader function in the root route and then render the data. 👉 Export a loader function from app/root.tsx and render the data The following code has a type error in it, we'll fix it in the next section // existing imports import { Form, Link, Links, Meta, Outlet, Scripts, ScrollRestoration, useLoaderData, } from \"@remix-run/react\"; // existing imports import { getContacts } from \"./data\"; // existing exports export const loader = async () =\u003e { const contacts = await getContacts(); return { contacts }; }; export default function App() { const { contacts } = useLoaderData(); return ( \u003chtml lang=\"en\"\u003e {/* other elements */} \u003cbody\u003e \u003cdiv id=\"sidebar\"\u003e {/* other elements */} \u003cnav\u003e {contacts.length ? ( \u003cul\u003e {contacts.map((contact) =\u003e ( \u003cli key={contact.id}\u003e \u003cLink to={`contacts/${contact.id}`}\u003e {contact.first || contact.last ? ( \u003c\u003e {contact.first} {contact.last} \u003c/\u003e ) : ( \u003ci\u003eNo Name\u003c/i\u003e )}{\" \"} {contact.favorite ? ( \u003cspan\u003e★\u003c/span\u003e ) : null} \u003c/Link\u003e \u003c/li\u003e ))} \u003c/ul\u003e ) : ( \u003cp\u003e \u003ci\u003eNo contacts\u003c/i\u003e \u003c/p\u003e )} \u003c/nav\u003e \u003c/div\u003e {/* other elements */} \u003c/body\u003e \u003c/html\u003e ); } That's it! Remix will now automatically keep that data in sync with your UI. The sidebar should now look like this: Type Inference You may have noticed TypeScript complaining about the contact type inside the map. We can add a quick annotation to get type inference about our data with typeof loader: // existing imports and exports export default function App() { const { contacts } = useLoaderData\u003ctypeof loader\u003e(); // existing code } URL Params in Loaders 👉 Click on one of the sidebar links We should be seeing our old static contact page again, with one difference: the URL now has a real ID for the record. Remember the $contactId part of the file name at app/routes/contacts.$contactId.tsx? These dynamic segments will match dynamic (changing) values in that position of the URL. We call these values in the URL \"URL Params\", or just \"params\" for short. These params are passed to the loader with keys that match the dynamic segment. For example, our segment is named $contactId so the value will be passed as params.contactId. These params are most often used to find a record by ID. Let's try it out. 👉 Add a loader function to the contact page and access data with useLoaderData The following code has type errors in it, we'll fix them in the next section import { Form, useLoaderData } from \"@remix-run/react\"; // existing imports import { getContact } from \"../data\"; export const loader = async ({ params }) =\u003e { const contact = await getContact(params.contactId); return { contact }; }; export default function Contact() { const { contact } = useLoaderData\u003ctypeof loader\u003e(); // existing code } // existing code Validating Params and Throwing Responses TypeScript is very upset with us, let's make it happy and see what that forces us to consider: import type { LoaderFunctionArgs } from \"@remix-run/node\"; // existing imports import invariant from \"tiny-invariant\"; // existing imports export const loader = async ({ params, }: LoaderFunctionArgs) =\u003e { invariant(params.contactId, \"Missing contactId param\"); const contact = await getContact(params.contactId); return { contact }; }; // existing code The first problem this highlights is we might have gotten the param's name wrong between the file name and the code (maybe you changed the name of the file!). Invariant is a handy function for throwing an error with a custom message when you anticipated a potential issue with your code. Next, the useLoaderData\u003ctypeof loader\u003e() now knows that we got a contact or null (maybe there is no contact with that ID). This potential null is cumbersome for our component code, and the TS errors are flying around still. We could account for the possibility of the contact being not found in component code, but the webby thing to do is send a proper 404. We can do that in the loader and solve all of our problems at once. // existing imports export const loader = async ({ params, }: LoaderFunctionArgs) =\u003e { invariant(params.contactId, \"Missing contactId param\"); const contact = await getContact(params.contactId); if (!contact) { throw new Response(\"Not Found\", { status: 404 }); } return { contact }; }; // existing code Now, if the user isn't found, code execution down this path stops and Remix renders the error path instead. Components in Remix can focus only on the happy path 😁 Data Mutations We'll create our first contact in a second, but first let's talk about HTML. Remix emulates HTML Form navigation as the data mutation primitive, which used to be the only way prior to the JavaScript cambrian explosion. Don't be fooled by the simplicity! Forms in Remix give you the UX capabilities of client-rendered apps with the simplicity of the \"old school\" web model. While unfamiliar to some web developers, HTML forms actually cause a navigation in the browser, just like clicking a link. The only difference is in the request: links can only change the URL while forms can also change the request method (GET vs. POST) and the request body (POST form data). Without client side routing, the browser will serialize the form's data automatically and send it to the server as the request body for POST, and as URLSearchParams for GET. Remix does the same thing, except instead of sending the request to the server, it uses client side routing and sends it to the route's action function. We can test this out by clicking the \"New\" button in our app. Remix sends a 405 because there is no code on the server to handle this form navigation. Creating Contacts We'll create new contacts by exporting an action function in our root route. When the user clicks the \"new\" button, the form will POST to the root route action. 👉 Export an action function from app/root.tsx // existing imports import { createEmptyContact, getContacts } from \"./data\"; export const action = async () =\u003e { const contact = await createEmptyContact(); return { contact }; }; // existing code That's it! Go ahead and click the \"New\" button, and you should see a new record pop into the list 🥳 The createEmptyContact method just creates an empty contact with no name or data or anything. But it does still create a record, promise! 🧐 Wait a sec ... How did the sidebar update? Where did we call the action function? Where's the code to re-fetch the data? Where are useState, onSubmit and useEffect?! This is where the \"old school web\" programming model shows up. \u003cForm\u003e prevents the browser from sending the request to the server and sends it to your route's action function instead with fetch. In web semantics, a POST usually means some data is changing. By convention, Remix uses this as a hint to automatically revalidate the data on the page after the action finishes. In fact, since it's all just HTML and HTTP, you could disable JavaScript and the whole thing will still work. Instead of Remix serializing the form and making a fetch request to your server, the browser will serialize the form and make a document request. From there Remix will render the page server side and send it down. It's the same UI in the end either way. We'll keep JavaScript around, though, because we're going to make a better user experience than spinning favicons and static documents. Updating Data Let's add a way to fill the information for our new record. Just like creating data, you update data with \u003cForm\u003e. Let's make a new route at app/routes/contacts.$contactId_.edit.tsx. 👉 Create the edit component touch app/routes/contacts.\\$contactId_.edit.tsx Note the weird _ in $contactId_. By default, routes will automatically nest inside routes with the same prefixed name. Adding a trailing _ tells the route to not nest inside app/routes/contacts.$contactId.tsx. Read more in the Route File Naming guide. 👉 Add the edit page UI Nothing we haven't seen before, feel free to copy/paste: import type { LoaderFunctionArgs } from \"@remix-run/node\"; import { Form, useLoaderData } from \"@remix-run/react\"; import invariant from \"tiny-invariant\"; import { getContact } from \"../data\"; export const loader = async ({ params, }: LoaderFunctionArgs) =\u003e { invariant(params.contactId, \"Missing contactId param\"); const contact = await getContact(params.contactId); if (!contact) { throw new Response(\"Not Found\", { status: 404 }); } return { contact }; }; export default function EditContact() { const { contact } = useLoaderData\u003ctypeof loader\u003e(); return ( \u003cForm key={contact.id} id=\"contact-form\" method=\"post\"\u003e \u003cp\u003e \u003cspan\u003eName\u003c/span\u003e \u003cinput aria-label=\"First name\" defaultValue={contact.first} name=\"first\" placeholder=\"First\" type=\"text\" /\u003e \u003cinput aria-label=\"Last name\" defaultValue={contact.last} name=\"last\" placeholder=\"Last\" type=\"text\" /\u003e \u003c/p\u003e \u003clabel\u003e \u003cspan\u003eTwitter\u003c/span\u003e \u003cinput defaultValue={contact.twitter} name=\"twitter\" placeholder=\"@jack\" type=\"text\" /\u003e \u003c/label\u003e \u003clabel\u003e \u003cspan\u003eAvatar URL\u003c/span\u003e \u003cinput aria-label=\"Avatar URL\" defaultValue={contact.avatar} name=\"avatar\" placeholder=\"https://example.com/avatar.jpg\" type=\"text\" /\u003e \u003c/label\u003e \u003clabel\u003e \u003cspan\u003eNotes\u003c/span\u003e \u003ctextarea defaultValue={contact.notes} name=\"notes\" rows={6} /\u003e \u003c/label\u003e \u003cp\u003e \u003cbutton type=\"submit\"\u003eSave\u003c/button\u003e \u003cbutton type=\"button\"\u003eCancel\u003c/button\u003e \u003c/p\u003e \u003c/Form\u003e ); } Now click on your new record, then click the \"Edit\" button. We should see the new route. Updating Contacts with FormData The edit route we just created already renders a form. All we need to do is add the action function. Remix will serialize the form, POST it with fetch, and automatically revalidate all the data. 👉 Add an action function to the edit route import type { ActionFunctionArgs, LoaderFunctionArgs, } from \"@remix-run/node\"; import { redirect } from \"@remix-run/node\"; // existing imports import { getContact, updateContact } from \"../data\"; export const action = async ({ params, request, }: ActionFunctionArgs) =\u003e { invariant(params.contactId, \"Missing contactId param\"); const formData = await request.formData(); const updates = Object.fromEntries(formData); await updateContact(params.contactId, updates); return redirect(`/contacts/${params.contactId}`); }; // existing code Fill out the form, hit save, and you should see something like this! (Except easier on the eyes and maybe less hairy.) Mutation Discussion 😑 It worked, but I have no idea what is going on here... Let's dig in a bit... Open up contacts.$contactId_.edit.tsx and look at the form elements. Notice how they each have a name: \u003cinput aria-label=\"First name\" defaultValue={contact.first} name=\"first\" placeholder=\"First\" type=\"text\" /\u003e Without JavaScript, when a form is submitted, the browser will create FormData and set it as the body of the request when it sends it to the server. As mentioned before, Remix prevents that and emulates the browser by sending the request to your action function with fetch instead, including the FormData. Each field in the form is accessible with formData.get(name). For example, given the input field from above, you could access the first and last names like this: export const action = async ({ params, request, }: ActionFunctionArgs) =\u003e { const formData = await request.formData(); const firstName = formData.get(\"first\"); const lastName = formData.get(\"last\"); // ... }; Since we have a handful of form fields, we used Object.fromEntries to collect them all into an object, which is exactly what our updateContact function wants. const updates = Object.fromEntries(formData); updates.first; // \"Some\" updates.last; // \"Name\" Aside from the action function, Remix provides none of these APIs we're discussing: request, request.formData, Object.fromEntries are all provided by the web platform. After we finished the action, note the redirect at the end: export const action = async ({ params, request, }: ActionFunctionArgs) =\u003e { invariant(params.contactId, \"Missing contactId param\"); const formData = await request.formData(); const updates = Object.fromEntries(formData); await updateContact(params.contactId, updates); return redirect(`/contacts/${params.contactId}`); }; action and loader functions can both return a Response (makes sense, since they received a Request!). The redirect helper just makes it easier to return a Response that tells the app to change locations. Without client side routing, if a server redirected after a POST request, the new page would fetch the latest data and render. As we learned before, Remix emulates this model and automatically revalidates the data on the page after the action call. That's why the sidebar automatically updates when we save the form. The extra revalidation code doesn't exist without client side routing, so it doesn't need to exist with client side routing in Remix either! One last thing. Without JavaScript, the redirect would be a normal redirect. However, with JavaScript it's a client-side redirect, so the user doesn't lose client state like scroll positions or component state. Redirecting new records to the edit page Now that we know how to redirect, let's update the action that creates new contacts to redirect to the edit page: 👉 Redirect to the new record's edit page // existing imports import { redirect } from \"@remix-run/node\"; // existing imports export const action = async () =\u003e { const contact = await createEmptyContact(); return redirect(`/contacts/${contact.id}/edit`); }; // existing code Now when we click \"New\", we should end up on the edit page: Active Link Styling Now that we have a bunch of records, it's not clear which one we're looking at in the sidebar. We can use NavLink to fix this. 👉 Replace \u003cLink\u003e with \u003cNavLink\u003e in the sidebar // existing imports import { Form, Links, Meta, NavLink, Outlet, Scripts, ScrollRestoration, useLoaderData, } from \"@remix-run/react\"; // existing imports and exports export default function App() { const { contacts } = useLoaderData\u003ctypeof loader\u003e(); return ( \u003chtml lang=\"en\"\u003e {/* existing elements */} \u003cbody\u003e \u003cdiv id=\"sidebar\"\u003e {/* existing elements */} \u003cul\u003e {contacts.map((contact) =\u003e ( \u003cli key={contact.id}\u003e \u003cNavLink className={({ isActive, isPending }) =\u003e isActive ? \"active\" : isPending ? \"pending\" : \"\" } to={`contacts/${contact.id}`} \u003e {/* existing elements */} \u003c/NavLink\u003e \u003c/li\u003e ))} \u003c/ul\u003e {/* existing elements */} \u003c/div\u003e {/* existing elements */} \u003c/body\u003e \u003c/html\u003e ); } Note that we are passing a function to className. When the user is at the URL that matches \u003cNavLink to\u003e, then isActive will be true. When it's about to be active (the data is still loading) then isPending will be true. This allows us to easily indicate where the user is and also provide immediate when links are clicked, but data needs to be loaded. Global Pending UI As the user navigates the app, Remix will leave the old page up as data is loading for the next page. You may have noticed the app feels a little unresponsive as you click between the list. Let's provide the user with some so the app doesn't feel unresponsive. Remix is managing all the states behind the scenes and reveals the pieces you need to build dynamic web apps. In this case, we'll use the useNavigation hook. 👉 Use useNavigation to add global pending UI // existing imports import { Form, Links, Meta, NavLink, Outlet, Scripts, ScrollRestoration, useLoaderData, useNavigation, } from \"@remix-run/react\"; // existing imports and exports export default function App() { const { contacts } = useLoaderData\u003ctypeof loader\u003e(); const navigation = useNavigation(); return ( \u003chtml lang=\"en\"\u003e {/* existing elements */} \u003cbody\u003e {/* existing elements */} \u003cdiv className={ navigation.state === \"loading\" ? \"loading\" : \"\" } id=\"detail\" \u003e \u003cOutlet /\u003e \u003c/div\u003e {/* existing elements */} \u003c/body\u003e \u003c/html\u003e ); } useNavigation returns the current navigation state: it can be one of \"idle\", \"loading\" or \"submitting\". In our case, we add a \"loading\" class to the main part of the app if we're not idle. The CSS then adds a nice fade after a short delay (to avoid flickering the UI for fast loads). You could do anything you want, though, like show a spinner or loading bar across the top. Deleting Records If we review code in the contact route, we can find the delete button looks like this: \u003cForm action=\"destroy\" method=\"post\" onSubmit={(event) =\u003e { const response = confirm( \"Please confirm you want to delete this record.\" ); if (!response) { event.preventDefault(); } }} \u003e \u003cbutton type=\"submit\"\u003eDelete\u003c/button\u003e \u003c/Form\u003e Note the action points to \"destroy\". Like \u003cLink to\u003e, \u003cForm action\u003e can take a relative value. Since the form is rendered in contacts.$contactId.tsx, then a relative action with destroy will submit the form to contacts.$contactId.destroy when clicked. At this point you should know everything you need to know to make the delete button work. Maybe give it a try before moving on? You'll need: A new route An action at that route deleteContact from app/data.ts redirect to somewhere after 👉 Create the \"destroy\" route module touch app/routes/contacts.\\$contactId_.destroy.tsx 👉 Add the destroy action import type { ActionFunctionArgs } from \"@remix-run/node\"; import { redirect } from \"@remix-run/node\"; import invariant from \"tiny-invariant\"; import { deleteContact } from \"../data\"; export const action = async ({ params, }: ActionFunctionArgs) =\u003e { invariant(params.contactId, \"Missing contactId param\"); await deleteContact(params.contactId); return redirect(\"/\"); }; Alright, navigate to a record and click the \"Delete\" button. It works! 😅 I'm still confused why this all works When the user clicks the submit button: \u003cForm\u003e prevents the default browser behavior of sending a new document POST request to the server, but instead emulates the browser by creating a POST request with client side routing and fetch The \u003cForm action=\"destroy\"\u003e matches the new route at contacts.$contactId_.destroy.tsx and sends it the request After the action redirects, Remix calls all the loaders for the data on the page to get the latest values (this is \"revalidation\"). useLoaderData returns new values and causes the components to update! Add a Form, add an action, Remix does the rest. Index Routes When we load up the app, you'll notice a big blank page on the right side of our list. When a route has children, and you're at the parent route's path, the \u003cOutlet\u003e has nothing to render because no children match. You can think of index routes as the default child route to fill in that space. 👉 Create an index route for the root route touch app/routes/_index.tsx 👉 Fill in the index component's elements Feel free to copy/paste, nothing special here. export default function Index() { return ( \u003cp id=\"index-page\"\u003e This is a demo for Remix. \u003cbr /\u003e Check out{\" \"} \u003ca href=\"https://remix.run\"\u003ethe docs at remix.run\u003c/a\u003e. \u003c/p\u003e ); } The route name _index is special. It tells Remix to match and render this route when the user is at the parent route's exact path, so there are no other child routes to render in the \u003cOutlet /\u003e. Voilà! No more blank space. It's common to put dashboards, stats, feeds, etc. at index routes. They can participate in data loading as well. Cancel Button On the edit page we've got a cancel button that doesn't do anything yet. We'd like it to do the same thing as the browser's back button. We'll need a click handler on the button as well as useNavigate. 👉 Add the cancel button click handler with useNavigate // existing imports import { Form, useLoaderData, useNavigate, } from \"@remix-run/react\"; // existing imports and exports export default function EditContact() { const { contact } = useLoaderData\u003ctypeof loader\u003e(); const navigate = useNavigate(); return ( \u003cForm key={contact.id} id=\"contact-form\" method=\"post\"\u003e {/* existing elements */} \u003cp\u003e \u003cbutton type=\"submit\"\u003eSave\u003c/button\u003e \u003cbutton onClick={() =\u003e navigate(-1)} type=\"button\"\u003e Cancel \u003c/button\u003e \u003c/p\u003e \u003c/Form\u003e ); } Now when the user clicks \"Cancel\", they'll be sent back one entry in the browser's history. 🧐 Why is there no event.preventDefault() on the button? A \u003cbutton type=\"button\"\u003e, while seemingly redundant, is the HTML way of preventing a button from submitting its form. Two more features to go. We're on the home stretch! URLSearchParams and GET Submissions All of our interactive UI so far have been either links that change the URL or forms that post data to action functions. The search field is interesting because it's a mix of both: it's a form, but it only changes the URL, it doesn't change data. Let's see what happens when we submit the search form: 👉 Type a name into the search field and hit the enter key Note the browser's URL now contains your query in the URL as URLSearchParams: http://localhost:5173/?q=ryan Since it's not \u003cForm method=\"post\"\u003e, Remix emulates the browser by serializing the FormData into the URLSearchParams instead of the request body. loader functions have access to the search params from the request. Let's use it to filter the list: 👉 Filter the list if there are URLSearchParams import type { LinksFunction, LoaderFunctionArgs, } from \"@remix-run/node\"; // existing imports and exports export const loader = async ({ request, }: LoaderFunctionArgs) =\u003e { const url = new URL(request.url); const q = url.searchParams.get(\"q\"); const contacts = await getContacts(q); return { contacts }; }; // existing code Because this is a GET, not a POST, Remix does not call the action function. Submitting a GET form is the same as clicking a link: only the URL changes. This also means it's a normal page navigation. You can click the back button to get back to where you were. Synchronizing URLs to Form State There are a couple of UX issues here that we can take care of quickly. If you click back after a search, the form field still has the value you entered even though the list is no longer filtered. If you refresh the page after searching, the form field no longer has the value in it, even though the list is filtered In other words, the URL and our input's state are out of sync. Let's solve (2) first and start the input with the value from the URL. 👉 Return q from your loader, set it as the input's default value // existing imports and exports export const loader = async ({ request, }: LoaderFunctionArgs) =\u003e { const url = new URL(request.url); const q = url.searchParams.get(\"q\"); const contacts = await getContacts(q); return { contacts, q }; }; export default function App() { const { contacts, q } = useLoaderData\u003ctypeof loader\u003e(); const navigation = useNavigation(); return ( \u003chtml lang=\"en\"\u003e {/* existing elements */} \u003cbody\u003e \u003cdiv id=\"sidebar\"\u003e {/* existing elements */} \u003cdiv\u003e \u003cForm id=\"search-form\" role=\"search\"\u003e \u003cinput aria-label=\"Search contacts\" defaultValue={q || \"\"} id=\"q\" name=\"q\" placeholder=\"Search\" type=\"search\" /\u003e {/* existing elements */} \u003c/Form\u003e {/* existing elements */} \u003c/div\u003e {/* existing elements */} \u003c/div\u003e {/* existing elements */} \u003c/body\u003e \u003c/html\u003e ); } The input field will show the query if you refresh the page after a search now. Now for problem (1), clicking the back button and updating the input. We can bring in useEffect from React to manipulate the input's value in the DOM directly. 👉 Synchronize input value with the URLSearchParams // existing imports import { useEffect } from \"react\"; // existing imports and exports export default function App() { const { contacts, q } = useLoaderData\u003ctypeof loader\u003e(); const navigation = useNavigation(); useEffect(() =\u003e { const searchField = document.getElementById(\"q\"); if (searchField instanceof HTMLInputElement) { searchField.value = q || \"\"; } }, [q]); // existing code } 🤔 Shouldn't you use a controlled component and React State for this? You could certainly do this as a controlled component. You will have more synchronization points, but it's up to you. Expand this to see what it would look like // We no longer need useEffect import { useState } from \"react\"; // existing imports and exports export default function App() { const { contacts, q } = useLoaderData\u003ctypeof loader\u003e(); const navigation = useNavigation(); // the query now needs to be kept in state const [prevQ, setPrevQ] = useState(q); const [query, setQuery] = useState(q || \"\"); // We can avoid using `useEffect` to synchronize the query // by using a separate piece of state to store the previous // value if (q !== prevQ) { setPrevQ(q); setQuery(q || \"\"); } return ( \u003chtml lang=\"en\"\u003e {/* existing elements */} \u003cbody\u003e \u003cdiv id=\"sidebar\"\u003e {/* existing elements */} \u003cdiv\u003e \u003cForm id=\"search-form\" role=\"search\"\u003e \u003cinput aria-label=\"Search contacts\" id=\"q\" name=\"q\" // synchronize user's input to component state onChange={(event) =\u003e setQuery(event.currentTarget.value) } placeholder=\"Search\" type=\"search\" // switched to `value` from `defaultValue` value={query} /\u003e {/* existing elements */} \u003c/Form\u003e {/* existing elements */} \u003c/div\u003e {/* existing elements */} \u003c/div\u003e {/* existing elements */} \u003c/body\u003e \u003c/html\u003e ); } Alright, you should now be able to click the back/forward/refresh buttons, and the input's value should be in sync with the URL and results. Submitting Form's onChange We've got a product decision to make here. Sometimes you want the user to submit the form to filter some results, other times you want to filter as the user types. We've already implemented the first, so let's see what it's like for the second. We've seen useNavigate already, we'll use its cousin, useSubmit, for this. // existing imports import { Form, Links, Meta, NavLink, Outlet, Scripts, ScrollRestoration, useLoaderData, useNavigation, useSubmit, } from \"@remix-run/react\"; // existing imports and exports export default function App() { const { contacts, q } = useLoaderData\u003ctypeof loader\u003e(); const navigation = useNavigation(); const submit = useSubmit(); // existing code return ( \u003chtml lang=\"en\"\u003e {/* existing elements */} \u003cbody\u003e \u003cdiv id=\"sidebar\"\u003e {/* existing elements */} \u003cdiv\u003e \u003cForm id=\"search-form\" onChange={(event) =\u003e submit(event.currentTarget) } role=\"search\" \u003e {/* existing elements */} \u003c/Form\u003e {/* existing elements */} \u003c/div\u003e {/* existing elements */} \u003c/div\u003e {/* existing elements */} \u003c/body\u003e \u003c/html\u003e ); } As you type, the form is automatically submitted now! Note the argument to submit. The submit function will serialize and submit any form you pass to it. We're passing in event.currentTarget. The currentTarget is the DOM node the event is attached to (the form). Adding Search Spinner In a production app, it's likely this search will be looking for records in a database that is too large to send all at once and filter client side. That's why this demo has some faked network latency. Without any loading indicator, the search feels kinda sluggish. Even if we could make our database faster, we'll always have the user's network latency in the way and out of our control. For a better user experience, let's add some immediate UI for the search. We'll use useNavigation again. 👉 Add a variable to know if we're searching // existing imports and exports export default function App() { const { contacts, q } = useLoaderData\u003ctypeof loader\u003e(); const navigation = useNavigation(); const submit = useSubmit(); const searching = navigation.location \u0026\u0026 new URLSearchParams(navigation.location.search).has( \"q\" ); // existing code } When nothing is happening, navigation.location will be undefined, but when the user navigates it will be populated with the next location while data loads. Then we check if they're searching with location.search. 👉 Add classes to search form elements using the new searching state // existing imports and exports export default function App() { // existing code return ( \u003chtml lang=\"en\"\u003e {/* existing elements */} \u003cbody\u003e \u003cdiv id=\"sidebar\"\u003e {/* existing elements */} \u003cdiv\u003e \u003cForm id=\"search-form\" onChange={(event) =\u003e submit(event.currentTarget) } role=\"search\" \u003e \u003cinput aria-label=\"Search contacts\" className={searching ? \"loading\" : \"\"} defaultValue={q || \"\"} id=\"q\" name=\"q\" placeholder=\"Search\" type=\"search\" /\u003e \u003cdiv aria-hidden hidden={!searching} id=\"search-spinner\" /\u003e \u003c/Form\u003e {/* existing elements */} \u003c/div\u003e {/* existing elements */} \u003c/div\u003e {/* existing elements */} \u003c/body\u003e \u003c/html\u003e ); } Bonus points, avoid fading out the main screen when searching: // existing imports and exports export default function App() { // existing code return ( \u003chtml lang=\"en\"\u003e {/* existing elements */} \u003cbody\u003e {/* existing elements */} \u003cdiv className={ navigation.state === \"loading\" \u0026\u0026 !searching ? \"loading\" : \"\" } id=\"detail\" \u003e \u003cOutlet /\u003e \u003c/div\u003e {/* existing elements */} \u003c/body\u003e \u003c/html\u003e ); } You should now have a nice spinner on the left side of the search input. Managing the History Stack Since the form is submitted for every keystroke, typing the characters \"alex\" and then deleting them with backspace results in a huge history stack 😂. We definitely don't want this: We can avoid this by replacing the current entry in the history stack with the next page instead of pushing into it. 👉 Use replace in submit // existing imports and exports export default function App() { // existing code return ( \u003chtml lang=\"en\"\u003e {/* existing elements */} \u003cbody\u003e \u003cdiv id=\"sidebar\"\u003e {/* existing elements */} \u003cdiv\u003e \u003cForm id=\"search-form\" onChange={(event) =\u003e { const isFirstSearch = q === null; submit(event.currentTarget, { replace: !isFirstSearch, }); }} role=\"search\" \u003e {/* existing elements */} \u003c/Form\u003e {/* existing elements */} \u003c/div\u003e {/* existing elements */} \u003c/div\u003e {/* existing elements */} \u003c/body\u003e \u003c/html\u003e ); } After a quick check if this is the first search or not, we decide to replace it. Now the first search will add a new entry, but every keystroke after that will replace the current entry. Instead of clicking back seven times to remove the search, users only have to click back once. Forms Without Navigation So far all of our forms have changed the URL. While these user flows are common, it's equally common to want to submit a form without causing a navigation. For these cases, we have useFetcher. It allows us to communicate with actions and loaders without causing a navigation. The ★ button on the contact page makes sense for this. We aren't creating or deleting a new record, and we don't want to change pages. We simply want to change the data on the page we're looking at. 👉 Change the \u003cFavorite\u003e form to a fetcher form // existing imports import { Form, useFetcher, useLoaderData, } from \"@remix-run/react\"; // existing imports and exports // existing code const Favorite: FunctionComponent\u003c{ contact: Pick\u003cContactRecord, \"favorite\"\u003e; }\u003e = ({ contact }) =\u003e { const fetcher = useFetcher(); const favorite = contact.favorite; return ( \u003cfetcher.Form method=\"post\"\u003e \u003cbutton aria-label={ favorite ? \"Remove from favorites\" : \"Add to favorites\" } name=\"favorite\" value={favorite ? \"false\" : \"true\"} \u003e {favorite ? \"★\" : \"☆\"} \u003c/button\u003e \u003c/fetcher.Form\u003e ); }; This form will no longer cause a navigation, but simply fetch to the action. Speaking of which ... this won't work until we create the action. 👉 Create the action import type { ActionFunctionArgs, LoaderFunctionArgs, } from \"@remix-run/node\"; // existing imports import { getContact, updateContact } from \"../data\"; // existing imports export const action = async ({ params, request, }: ActionFunctionArgs) =\u003e { invariant(params.contactId, \"Missing contactId param\"); const formData = await request.formData(); return updateContact(params.contactId, { favorite: formData.get(\"favorite\") === \"true\", }); }; // existing code Alright, we're ready to click the star next to the user's name! Check that out, both stars automatically update. Our new \u003cfetcher.Form method=\"post\"\u003e works almost exactly like the \u003cForm\u003e we've been using: it calls the action and then all data is revalidated automatically — even your errors will be caught the same way. There is one key difference, though, it's not a navigation, so the URL doesn't change, and the history stack is unaffected. Optimistic UI You probably noticed the app felt kind of unresponsive when we clicked the favorite button from the last section. Once again, we added some network latency because you're going to have it in the real world. To give the user some , we could put the star into a loading state with fetcher.state (a lot like navigation.state from before), but we can do something even better this time. We can use a strategy called \"Optimistic UI\". The fetcher knows the FormData being submitted to the action, so it's available to you on fetcher.formData. We'll use that to immediately update the star's state, even though the network hasn't finished. If the update eventually fails, the UI will revert to the real data. 👉 Read the optimistic value from fetcher.formData // existing code const Favorite: FunctionComponent\u003c{ contact: Pick\u003cContactRecord, \"favorite\"\u003e; }\u003e = ({ contact }) =\u003e { const fetcher = useFetcher(); const favorite = fetcher.formData ? fetcher.formData.get(\"favorite\") === \"true\" : contact.favorite; return ( \u003cfetcher.Form method=\"post\"\u003e \u003cbutton aria-label={ favorite ? \"Remove from favorites\" : \"Add to favorites\" } name=\"favorite\" value={favorite ? \"false\" : \"true\"} \u003e {favorite ? \"★\" : \"☆\"} \u003c/button\u003e \u003c/fetcher.Form\u003e ); }; Now the star immediately changes to the new state when you click it. That's it! Thanks for giving Remix a try. We hope this tutorial gives you a solid start to build great user experiences. There's a lot more you can do, so make sure to check out all the APIs 😀© 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,\\\"_1047\\\":-5,\\\"_1048\\\":-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\\\":1046},{\\\"_18\\\":38,\\\"_20\\\":39},\\\"docs/start/tutorial.md\\\",\\\"html\\\",\\\"\\u003ch1 id=\\\\\\\"remix-tutorial\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#remix-tutorial\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eRemix Tutorial\\u003c/h1\\u003e\\\\n\\u003cp\\u003e\\u003cdocs-warning\\u003eJust getting started with Remix? The latest version of \\u003ca href=\\\\\\\"https://remix.run/blog/incremental-path-to-react-19\\\\\\\"\\u003eRemix is now React Router v7\\u003c/a\\u003e. If you want to use the latest framework features, you can follow the same \\u003ca href=\\\\\\\"https://reactrouter.com/tutorials/address-book\\\\\\\"\\u003etutorial from the React Router docs\\u003c/a\\u003e.\\u003c/docs-warning\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eWe'll be building a small, but feature-rich app that lets you keep track of your contacts. There's no database or other \\\\\\\"production ready\\\\\\\" things, so we can stay focused on Remix. We expect it to take about 30 m if you're following along, otherwise it's a quick read.\\u003c/p\\u003e\\\\n\\u003cimg class=\\\\\\\"tutorial\\\\\\\" src=\\\\\\\"/docs-images/contacts/01.webp\\\\\\\" /\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eEvery time you see this, it means you need to do something in the app!\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eThe rest is just there for your information and deeper understanding. Let's get to it.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"setup\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#setup\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eSetup\\u003c/h2\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eGenerate a basic template\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\"\\u003e\\u003cpre data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003enpx\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003ecreate-remix@latest\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e--template\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eremix-run/remix/templates/remix-tutorial\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eThis uses a pretty bare-bones template but includes our CSS and data model, so we can focus on Remix. The \\u003ca href=\\\\\\\"./quickstart\\\\\\\"\\u003eQuick Start\\u003c/a\\u003e can familiarize you with the basic setup of a Remix project if you'd like to learn more.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eStart the app\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\"\\u003e\\u003cpre data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e# cd into the app directory\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ecd\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e{wherever\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eyou\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eput\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003ethe\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eapp}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e# install dependencies if you haven't already\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003enpm\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003einstall\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e# start the server\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003enpm\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003erun\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003edev\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eYou should be able to open up \\u003ca href=\\\\\\\"http://localhost:5173\\\\\\\"\\u003ehttp://localhost:5173\\u003c/a\\u003e and see an unstyled screen that looks like this:\\u003c/p\\u003e\\\\n\\u003cimg class=\\\\\\\"tutorial\\\\\\\" src=\\\\\\\"/docs-images/contacts/03.webp\\\\\\\" /\\u003e\\\\n\\u003ch2 id=\\\\\\\"the-root-route\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#the-root-route\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eThe Root Route\\u003c/h2\\u003e\\\\n\\u003cp\\u003eNote the file at \\u003ccode\\u003eapp/root.tsx\\u003c/code\\u003e. This is what we call the \\\\\\\"Root Route\\\\\\\". It's the first component in the UI that renders, so it typically contains the global layout for the page.\\u003c/p\\u003e\\\\n\\u003cdetails\\u003e\\\\n\\u003csummary\\u003eExpand here to see the root component code\\u003c/summary\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/root.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/root.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)\\\\\\\"\\u003eimport\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eForm\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eLinks\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eMeta\\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)\\\\\\\"\\u003eApp\\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(--base08)\\\\\\\"\\u003emeta\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003echarSet\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eutf-8\\u003c/span\\u003e\\\\\\\" /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003emeta\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ename\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eviewport\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003econtent\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003ewidth=device-width, initial-scale=1\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eMeta\\u003c/span\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eLinks\\u003c/span\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"20\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ehead\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"21\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"22\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esidebar\\u003c/span\\u003e\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"23\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eh1\\u003c/span\\u003e\\u003eRemix Contacts\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eh1\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"24\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"25\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esearch-form\\u003c/span\\u003e\\\\\\\" \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003erole\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esearch\\u003c/span\\u003e\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"26\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003einput\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"27\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003earia-label\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eSearch contacts\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"28\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eq\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"29\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ename\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eq\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"30\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eplaceholder\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eSearch\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"31\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003etype\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esearch\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"32\\\\\\\"\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"33\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"34\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003earia-hidden\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"35\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ehidden\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base09)\\\\\\\"\\u003etrue\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"36\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esearch-spinner\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"37\\\\\\\"\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"38\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"39\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003emethod\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003epost\\u003c/span\\u003e\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"40\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebutton\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003etype\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esubmit\\u003c/span\\u003e\\\\\\\"\\u003eNew\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebutton\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"41\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"42\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"43\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003enav\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"44\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eul\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"45\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eli\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"46\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ea\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ehref\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e`\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e/contacts/1\\u003c/span\\u003e`\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\u003eYour Name\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ea\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"47\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eli\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"48\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eli\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"49\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ea\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ehref\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e`\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e/contacts/2\\u003c/span\\u003e`\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\u003eYour Friend\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ea\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"50\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eli\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"51\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eul\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"52\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003enav\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"53\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"54\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"55\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eScrollRestoration\\u003c/span\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"56\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eScripts\\u003c/span\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"57\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"58\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ehtml\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"59\\\\\\\"\\u003e );\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"60\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003c/details\\u003e\\\\n\\u003ch2 id=\\\\\\\"adding-stylesheets-with-links\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#adding-stylesheets-with-links\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eAdding Stylesheets with \\u003ccode\\u003elinks\\u003c/code\\u003e\\u003c/h2\\u003e\\\\n\\u003cp\\u003eWhile there are multiple ways to style your Remix app, we're going to use a plain stylesheet that's already been written to keep things focused on Remix.\\u003c/p\\u003e\\\\n\\u003cp\\u003eYou can import CSS files directly into JavaScript modules. Vite will fingerprint the asset, save it to your build's client directory, and provide your module with the publicly accessible href.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eImport the app styles\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/root.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/root.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etype\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eLinksFunction\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/node\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing imports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eappStylesHref\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e./app.css?url\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003elinks\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eLinksFunction\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e () \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e [\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e { rel: \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003estylesheet\\u003c/span\\u003e\\\\\\\", href: \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eappStylesHref\\u003c/span\\u003e },\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e];\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eEvery route can export a \\u003ca href=\\\\\\\"../route/links\\\\\\\"\\u003e\\u003ccode\\u003elinks\\u003c/code\\u003e\\u003c/a\\u003e function. They will be collected and rendered into the \\u003ccode\\u003e\\u0026#x3C;Links /\\u003e\\u003c/code\\u003e component we rendered in \\u003ccode\\u003eapp/root.tsx\\u003c/code\\u003e.\\u003c/p\\u003e\\\\n\\u003cp\\u003eThe app should look something like this now. It sure is nice having a designer who can also write the CSS, isn't it? (Thank you, \\u003ca href=\\\\\\\"https://blog.jim-nielsen.com\\\\\\\"\\u003eJim\\u003c/a\\u003e 🙏).\\u003c/p\\u003e\\\\n\\u003cimg class=\\\\\\\"tutorial\\\\\\\" loading=\\\\\\\"lazy\\\\\\\" src=\\\\\\\"/docs-images/contacts/04.webp\\\\\\\" /\\u003e\\\\n\\u003ch2 id=\\\\\\\"the-contact-route-ui\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#the-contact-route-ui\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eThe Contact Route UI\\u003c/h2\\u003e\\\\n\\u003cp\\u003eIf you click on one of the sidebar items, you'll get the default 404 page. Let's create a route that matches the url \\u003ccode\\u003e/contacts/1\\u003c/code\\u003e.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eCreate the \\u003ccode\\u003eapp/routes\\u003c/code\\u003e directory and contact route module\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\"\\u003e\\u003cpre data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003emkdir\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eapp/routes\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003etouch\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eapp/routes/contacts.\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0C)\\\\\\\"\\u003e\\\\\\\\$\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003econtactId.tsx\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eIn the Remix \\u003ca href=\\\\\\\"../file-conventions/routes\\\\\\\"\\u003eroute file convention\\u003c/a\\u003e, \\u003ccode\\u003e.\\u003c/code\\u003e will create a \\u003ccode\\u003e/\\u003c/code\\u003e in the URL and \\u003ccode\\u003e$\\u003c/code\\u003e makes a segment dynamic. We just created a route that will match URLs that look like this:\\u003c/p\\u003e\\\\n\\u003cul\\u003e\\\\n\\u003cli\\u003e\\u003ccode\\u003e/contacts/123\\u003c/code\\u003e\\u003c/li\\u003e\\\\n\\u003cli\\u003e\\u003ccode\\u003e/contacts/abc\\u003c/code\\u003e\\u003c/li\\u003e\\\\n\\u003c/ul\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eAdd the contact component UI\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eIt's just a bunch of elements, feel free to copy/paste.\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/routes/contacts.$contactId.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/routes/contacts.$contactId.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)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eForm\\u003c/span\\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=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etype\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eFunctionComponent\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003ereact\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etype\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eContactRecord\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e../data\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\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)\\\\\\\"\\u003eContact\\u003c/span\\u003e() {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e first: \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eYour\\u003c/span\\u003e\\\\\\\",\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e last: \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eName\\u003c/span\\u003e\\\\\\\",\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e avatar: \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003ehttps://placecats.com/200/200\\u003c/span\\u003e\\\\\\\",\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e twitter: \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eyour_handle\\u003c/span\\u003e\\\\\\\",\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e notes: \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eSome notes\\u003c/span\\u003e\\\\\\\",\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e favorite: \\u003cspan style=\\\\\\\"color: var(--base09)\\\\\\\"\\u003etrue\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e };\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003econtact\\u003c/span\\u003e\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eimg\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"20\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ealt\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e`${\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efirst\\u003c/span\\u003e}\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e \\u003c/span\\u003e${\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003elast\\u003c/span\\u003e}\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e avatar\\u003c/span\\u003e`\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"21\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ekey\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eavatar\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"22\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003esrc\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eavatar\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"23\\\\\\\"\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"24\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"25\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"26\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"27\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eh1\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"28\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efirst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e||\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003elast\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e?\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"29\\\\\\\"\\u003e \\u0026#x3C;\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"30\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efirst\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003elast\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"31\\\\\\\"\\u003e \\u0026#x3C;/\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"32\\\\\\\"\\u003e ) \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"33\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ei\\u003c/span\\u003e\\u003eNo Name\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ei\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"34\\\\\\\"\\u003e )\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}{\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e \\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"35\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eFavorite\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003econtact\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"36\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eh1\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"37\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"38\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003etwitter\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e?\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"39\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ep\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"40\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ea\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"41\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ehref\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e`\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003ehttps://twitter.com/\\u003c/span\\u003e${\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003etwitter\\u003c/span\\u003e}`\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"42\\\\\\\"\\u003e \\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"43\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003etwitter\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"44\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ea\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"45\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ep\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"46\\\\\\\"\\u003e ) \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base09)\\\\\\\"\\u003enull\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"47\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"48\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003enotes\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e?\\u003c/span\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ep\\u003c/span\\u003e\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003enotes\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ep\\u003c/span\\u003e\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base09)\\\\\\\"\\u003enull\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"49\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"50\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"51\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eaction\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eedit\\u003c/span\\u003e\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"52\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebutton\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003etype\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esubmit\\u003c/span\\u003e\\\\\\\"\\u003eEdit\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebutton\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"53\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"54\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"55\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"56\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eaction\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003edestroy\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"57\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003emethod\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003epost\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"58\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eonSubmit\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eevent\\u003c/span\\u003e) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"59\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eresponse\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003econfirm\\u003c/span\\u003e(\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"60\\\\\\\"\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003ePlease confirm you want to delete this record.\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"61\\\\\\\"\\u003e );\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"62\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eif\\u003c/span\\u003e (\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e!\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eresponse\\u003c/span\\u003e) {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"63\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eevent\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003epreventDefault\\u003c/span\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"64\\\\\\\"\\u003e }\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"65\\\\\\\"\\u003e }\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"66\\\\\\\"\\u003e \\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"67\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebutton\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003etype\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esubmit\\u003c/span\\u003e\\\\\\\"\\u003eDelete\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebutton\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"68\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"69\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"70\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"71\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"72\\\\\\\"\\u003e );\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"73\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"74\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"75\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eFavorite\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eFunctionComponent\\u003c/span\\u003e\\u0026#x3C;{\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"76\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003ePick\\u003c/span\\u003e\\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eContactRecord\\u003c/span\\u003e, \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003efavorite\\u003c/span\\u003e\\\\\\\"\\u003e;\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"77\\\\\\\"\\u003e}\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e ({ \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e }) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"78\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efavorite\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efavorite\\u003c/span\\u003e;\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"79\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"80\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"81\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003emethod\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003epost\\u003c/span\\u003e\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"82\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebutton\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"83\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003earia-label\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"84\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efavorite\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"85\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e?\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eRemove from favorites\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"86\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eAdd to favorites\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"87\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"88\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ename\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003efavorite\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"89\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003evalue\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efavorite\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e?\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003efalse\\u003c/span\\u003e\\\\\\\" \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003etrue\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"90\\\\\\\"\\u003e \\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"91\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efavorite\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e?\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e★\\u003c/span\\u003e\\\\\\\" \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e☆\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"92\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebutton\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"93\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"94\\\\\\\"\\u003e );\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"95\\\\\\\"\\u003e};\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eNow if we click one of the links or visit \\u003ccode\\u003e/contacts/1\\u003c/code\\u003e we get ... nothing new?\\u003c/p\\u003e\\\\n\\u003cimg class=\\\\\\\"tutorial\\\\\\\" loading=\\\\\\\"lazy\\\\\\\" alt=\\\\\\\"contact route with blank main content\\\\\\\" src=\\\\\\\"/docs-images/contacts/05.webp\\\\\\\" /\\u003e\\\\n\\u003ch2 id=\\\\\\\"nested-routes-and-outlets\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#nested-routes-and-outlets\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eNested Routes and Outlets\\u003c/h2\\u003e\\\\n\\u003cp\\u003eSince Remix is built on top of React Router, it supports nested routing. In order for child routes to render inside parent layouts, we need to render an \\u003ca href=\\\\\\\"../components/outlet\\\\\\\"\\u003e\\u003ccode\\u003eOutlet\\u003c/code\\u003e\\u003c/a\\u003e in the parent. Let's fix it, open up \\u003ccode\\u003eapp/root.tsx\\u003c/code\\u003e and render an outlet inside.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eRender an \\u003ca href=\\\\\\\"../components/outlet\\\\\\\"\\u003e\\u003ccode\\u003e\\u0026#x3C;Outlet /\\u003e\\u003c/code\\u003e\\u003c/a\\u003e\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/root.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/root.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(--base03)\\\\\\\"\\u003e// existing imports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eForm\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eLinks\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eMeta\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eOutlet\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eScripts\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eScrollRestoration\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\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=\\\\\\\"10\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing imports \\u0026#x26; code\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\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)\\\\\\\"\\u003eApp\\u003c/span\\u003e() {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\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=\\\\\\\"16\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* other elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esidebar\\u003c/span\\u003e\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* other elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003edetail\\u003c/span\\u003e\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"20\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eOutlet\\u003c/span\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"21\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"22\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* other elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"23\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"24\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ehtml\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"25\\\\\\\"\\u003e );\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"26\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eNow the child route should be rendered through the outlet.\\u003c/p\\u003e\\\\n\\u003cimg class=\\\\\\\"tutorial\\\\\\\" loading=\\\\\\\"lazy\\\\\\\" alt=\\\\\\\"contact route with the main content\\\\\\\" src=\\\\\\\"/docs-images/contacts/06.webp\\\\\\\" /\\u003e\\\\n\\u003ch2 id=\\\\\\\"client-side-routing\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#client-side-routing\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eClient Side Routing\\u003c/h2\\u003e\\\\n\\u003cp\\u003eYou may or may not have noticed, but when we click the links in the sidebar, the browser is doing a full document request for the next URL instead of client side routing.\\u003c/p\\u003e\\\\n\\u003cp\\u003eClient side routing allows our app to update the URL without requesting another document from the server. Instead, the app can immediately render a new UI. Let's make it happen with \\u003ca href=\\\\\\\"../components/link\\\\\\\"\\u003e\\u003ccode\\u003e\\u0026#x3C;Link\\u003e\\u003c/code\\u003e\\u003c/a\\u003e.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eChange the sidebar \\u003ccode\\u003e\\u0026#x3C;a href\\u003e\\u003c/code\\u003e to \\u003ccode\\u003e\\u0026#x3C;Link to\\u003e\\u003c/code\\u003e\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/root.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/root.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(--base03)\\\\\\\"\\u003e// existing imports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eForm\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eLink\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eLinks\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eMeta\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eOutlet\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eScripts\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eScrollRestoration\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\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=\\\\\\\"11\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing imports and exports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\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)\\\\\\\"\\u003eApp\\u003c/span\\u003e() {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\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=\\\\\\\"17\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* other elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esidebar\\u003c/span\\u003e\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"20\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* other elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"21\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003enav\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"22\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eul\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"23\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eli\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"24\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eLink\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eto\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e`\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e/contacts/1\\u003c/span\\u003e`\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\u003eYour Name\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eLink\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"25\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eli\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"26\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eli\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"27\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eLink\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eto\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e`\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e/contacts/2\\u003c/span\\u003e`\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\u003eYour Friend\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eLink\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"28\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eli\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"29\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eul\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"30\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003enav\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"31\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"32\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* other elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"33\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"34\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ehtml\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"35\\\\\\\"\\u003e );\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"36\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eYou can open the network tab in the browser devtools to see that it's not requesting documents anymore.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"loading-data\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#loading-data\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eLoading Data\\u003c/h2\\u003e\\\\n\\u003cp\\u003eURL segments, layouts, and data are more often than not coupled (tripled?) together. We can see it in this app already:\\u003c/p\\u003e\\\\n\\u003ctable\\u003e\\\\n\\u003cthead\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003cth\\u003eURL Segment\\u003c/th\\u003e\\\\n\\u003cth\\u003eComponent\\u003c/th\\u003e\\\\n\\u003cth\\u003eData\\u003c/th\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003c/thead\\u003e\\\\n\\u003ctbody\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003e/\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e\\u0026#x3C;Root\\u003e\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003elist of contacts\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003ctr\\u003e\\\\n\\u003ctd\\u003econtacts/:contactId\\u003c/td\\u003e\\\\n\\u003ctd\\u003e\\u003ccode\\u003e\\u0026#x3C;Contact\\u003e\\u003c/code\\u003e\\u003c/td\\u003e\\\\n\\u003ctd\\u003eindividual contact\\u003c/td\\u003e\\\\n\\u003c/tr\\u003e\\\\n\\u003c/tbody\\u003e\\\\n\\u003c/table\\u003e\\\\n\\u003cp\\u003eBecause of this natural coupling, Remix has data conventions to get data into your route components easily.\\u003c/p\\u003e\\\\n\\u003cp\\u003eThere are two APIs we'll be using to load data, \\u003ca href=\\\\\\\"../route/loader\\\\\\\"\\u003e\\u003ccode\\u003eloader\\u003c/code\\u003e\\u003c/a\\u003e and \\u003ca href=\\\\\\\"../hooks/use-loader-data\\\\\\\"\\u003e\\u003ccode\\u003euseLoaderData\\u003c/code\\u003e\\u003c/a\\u003e. First we'll create and export a \\u003ccode\\u003eloader\\u003c/code\\u003e function in the root route and then render the data.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eExport a \\u003ccode\\u003eloader\\u003c/code\\u003e function from \\u003ccode\\u003eapp/root.tsx\\u003c/code\\u003e and render the data\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003e\\u003cdocs-info\\u003eThe following code has a type error in it, we'll fix it in the next section\\u003c/docs-info\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/root.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/root.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(--base03)\\\\\\\"\\u003e// existing imports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eForm\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eLink\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eLinks\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eMeta\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eOutlet\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eScripts\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eScrollRestoration\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003euseLoaderData\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\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=\\\\\\\"12\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing imports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003egetContacts\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e./data\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing exports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eloader\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003easync\\u003c/span\\u003e () \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtacts\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eawait\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003egetContacts\\u003c/span\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"20\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtacts\\u003c/span\\u003e };\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"21\\\\\\\"\\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\\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)\\\\\\\"\\u003eApp\\u003c/span\\u003e() {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"24\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtacts\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseLoaderData\\u003c/span\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"25\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"26\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"27\\\\\\\"\\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=\\\\\\\"28\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* other elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"29\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"30\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esidebar\\u003c/span\\u003e\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"31\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* other elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"32\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003enav\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"33\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtacts\\u003c/span\\u003e.length \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e?\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"34\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eul\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"35\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtacts\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003emap\\u003c/span\\u003e((\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"36\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eli\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ekey\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"37\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eLink\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eto\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e`\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003econtacts/\\u003c/span\\u003e${\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eid\\u003c/span\\u003e}`\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"38\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efirst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e||\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003elast\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e?\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"39\\\\\\\"\\u003e \\u0026#x3C;\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"40\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efirst\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003elast\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"41\\\\\\\"\\u003e \\u0026#x3C;/\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"42\\\\\\\"\\u003e ) \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"43\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ei\\u003c/span\\u003e\\u003eNo Name\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ei\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"44\\\\\\\"\\u003e )\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}{\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e \\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"45\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efavorite\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e?\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"46\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003espan\\u003c/span\\u003e\\u003e★\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003espan\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"47\\\\\\\"\\u003e ) \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base09)\\\\\\\"\\u003enull\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"48\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eLink\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"49\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eli\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"50\\\\\\\"\\u003e ))\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"51\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eul\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"52\\\\\\\"\\u003e ) \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"53\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ep\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"54\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ei\\u003c/span\\u003e\\u003eNo contacts\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ei\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"55\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ep\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"56\\\\\\\"\\u003e )\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"57\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003enav\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"58\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"59\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* other elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"60\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"61\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ehtml\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"62\\\\\\\"\\u003e );\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"63\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eThat's it! Remix will now automatically keep that data in sync with your UI. The sidebar should now look like this:\\u003c/p\\u003e\\\\n\\u003cimg class=\\\\\\\"tutorial\\\\\\\" loading=\\\\\\\"lazy\\\\\\\" src=\\\\\\\"/docs-images/contacts/07.webp\\\\\\\" /\\u003e\\\\n\\u003ch2 id=\\\\\\\"type-inference\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#type-inference\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eType Inference\\u003c/h2\\u003e\\\\n\\u003cp\\u003eYou may have noticed TypeScript complaining about the \\u003ccode\\u003econtact\\u003c/code\\u003e type inside the map. We can add a quick annotation to get type inference about our data with \\u003ccode\\u003etypeof loader\\u003c/code\\u003e:\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/root.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/root.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(--base03)\\\\\\\"\\u003e// existing imports and exports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\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)\\\\\\\"\\u003eApp\\u003c/span\\u003e() {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtacts\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseLoaderData\\u003c/span\\u003e\\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etypeof\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eloader\\u003c/span\\u003e\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing code\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003ch2 id=\\\\\\\"url-params-in-loaders\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#url-params-in-loaders\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eURL Params in Loaders\\u003c/h2\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eClick on one of the sidebar links\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eWe should be seeing our old static contact page again, with one difference: the URL now has a real ID for the record.\\u003c/p\\u003e\\\\n\\u003cimg class=\\\\\\\"tutorial\\\\\\\" loading=\\\\\\\"lazy\\\\\\\" src=\\\\\\\"/docs-images/contacts/08.webp\\\\\\\" /\\u003e\\\\n\\u003cp\\u003eRemember the \\u003ccode\\u003e$contactId\\u003c/code\\u003e part of the file name at \\u003ccode\\u003eapp/routes/contacts.$contactId.tsx\\u003c/code\\u003e? These dynamic segments will match dynamic (changing) values in that position of the URL. We call these values in the URL \\\\\\\"URL Params\\\\\\\", or just \\\\\\\"params\\\\\\\" for short.\\u003c/p\\u003e\\\\n\\u003cp\\u003eThese \\u003ca href=\\\\\\\"../route/loader#params\\\\\\\"\\u003e\\u003ccode\\u003eparams\\u003c/code\\u003e\\u003c/a\\u003e are passed to the loader with keys that match the dynamic segment. For example, our segment is named \\u003ccode\\u003e$contactId\\u003c/code\\u003e so the value will be passed as \\u003ccode\\u003eparams.contactId\\u003c/code\\u003e.\\u003c/p\\u003e\\\\n\\u003cp\\u003eThese params are most often used to find a record by ID. Let's try it out.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eAdd a \\u003ccode\\u003eloader\\u003c/code\\u003e function to the contact page and access data with \\u003ccode\\u003euseLoaderData\\u003c/code\\u003e\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003e\\u003cdocs-info\\u003eThe following code has type errors in it, we'll fix them in the next section\\u003c/docs-info\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/routes/contacts.$contactId.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/routes/contacts.$contactId.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eForm\\u003c/span\\u003e, \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003euseLoaderData\\u003c/span\\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=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing imports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003egetContact\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e../data\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eloader\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003easync\\u003c/span\\u003e ({ \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e }) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eawait\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003egetContact\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtactId\\u003c/span\\u003e);\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e };\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e};\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\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)\\\\\\\"\\u003eContact\\u003c/span\\u003e() {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseLoaderData\\u003c/span\\u003e\\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etypeof\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eloader\\u003c/span\\u003e\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing code\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing code\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cimg class=\\\\\\\"tutorial\\\\\\\" loading=\\\\\\\"lazy\\\\\\\" src=\\\\\\\"/docs-images/contacts/10.webp\\\\\\\" /\\u003e\\\\n\\u003ch2 id=\\\\\\\"validating-params-and-throwing-responses\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#validating-params-and-throwing-responses\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eValidating Params and Throwing Responses\\u003c/h2\\u003e\\\\n\\u003cp\\u003eTypeScript is very upset with us, let's make it happy and see what that forces us to consider:\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/routes/contacts.$contactId.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/routes/contacts.$contactId.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etype\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eLoaderFunctionArgs\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/node\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing imports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003einvariant\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003etiny-invariant\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing imports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eloader\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003easync\\u003c/span\\u003e ({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e}\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eLoaderFunctionArgs\\u003c/span\\u003e) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003einvariant\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtactId\\u003c/span\\u003e, \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eMissing contactId param\\u003c/span\\u003e\\\\\\\");\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eawait\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003egetContact\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtactId\\u003c/span\\u003e);\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e };\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e};\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing code\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eThe first problem this highlights is we might have gotten the param's name wrong between the file name and the code (maybe you changed the name of the file!). Invariant is a handy function for throwing an error with a custom message when you anticipated a potential issue with your code.\\u003c/p\\u003e\\\\n\\u003cp\\u003eNext, the \\u003ccode\\u003euseLoaderData\\u0026#x3C;typeof loader\\u003e()\\u003c/code\\u003e now knows that we got a contact or \\u003ccode\\u003enull\\u003c/code\\u003e (maybe there is no contact with that ID). This potential \\u003ccode\\u003enull\\u003c/code\\u003e is cumbersome for our component code, and the TS errors are flying around still.\\u003c/p\\u003e\\\\n\\u003cp\\u003eWe could account for the possibility of the contact being not found in component code, but the webby thing to do is send a proper 404. We can do that in the loader and solve all of our problems at once.\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/routes/contacts.$contactId.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/routes/contacts.$contactId.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(--base03)\\\\\\\"\\u003e// existing imports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eloader\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003easync\\u003c/span\\u003e ({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e}\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eLoaderFunctionArgs\\u003c/span\\u003e) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003einvariant\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtactId\\u003c/span\\u003e, \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eMissing contactId param\\u003c/span\\u003e\\\\\\\");\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eawait\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003egetContact\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtactId\\u003c/span\\u003e);\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eif\\u003c/span\\u003e (\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e!\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e) {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ethrow\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003enew\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eResponse\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eNot Found\\u003c/span\\u003e\\\\\\\", { status: \\u003cspan style=\\\\\\\"color: var(--base09)\\\\\\\"\\u003e404\\u003c/span\\u003e });\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e }\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e };\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e};\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing code\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eNow, if the user isn't found, code execution down this path stops and Remix renders the error path instead. Components in Remix can focus only on the happy path 😁\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"data-mutations\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#data-mutations\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eData Mutations\\u003c/h2\\u003e\\\\n\\u003cp\\u003eWe'll create our first contact in a second, but first let's talk about HTML.\\u003c/p\\u003e\\\\n\\u003cp\\u003eRemix emulates HTML Form navigation as the data mutation primitive, which used to be the only way prior to the JavaScript cambrian explosion. Don't be fooled by the simplicity! Forms in Remix give you the UX capabilities of client-rendered apps with the simplicity of the \\\\\\\"old school\\\\\\\" web model.\\u003c/p\\u003e\\\\n\\u003cp\\u003eWhile unfamiliar to some web developers, HTML \\u003ccode\\u003eform\\u003c/code\\u003es actually cause a navigation in the browser, just like clicking a link. The only difference is in the request: links can only change the URL while \\u003ccode\\u003eform\\u003c/code\\u003es can also change the request method (\\u003ccode\\u003eGET\\u003c/code\\u003e vs. \\u003ccode\\u003ePOST\\u003c/code\\u003e) and the request body (\\u003ccode\\u003ePOST\\u003c/code\\u003e form data).\\u003c/p\\u003e\\\\n\\u003cp\\u003eWithout client side routing, the browser will serialize the \\u003ccode\\u003eform\\u003c/code\\u003e's data automatically and send it to the server as the request body for \\u003ccode\\u003ePOST\\u003c/code\\u003e, and as \\u003ca href=\\\\\\\"https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams\\\\\\\"\\u003e\\u003ccode\\u003eURLSearchParams\\u003c/code\\u003e\\u003c/a\\u003e for \\u003ccode\\u003eGET\\u003c/code\\u003e. Remix does the same thing, except instead of sending the request to the server, it uses client side routing and sends it to the route's \\u003ca href=\\\\\\\"../route/action\\\\\\\"\\u003e\\u003ccode\\u003eaction\\u003c/code\\u003e\\u003c/a\\u003e function.\\u003c/p\\u003e\\\\n\\u003cp\\u003eWe can test this out by clicking the \\\\\\\"New\\\\\\\" button in our app.\\u003c/p\\u003e\\\\n\\u003cimg class=\\\\\\\"tutorial\\\\\\\" loading=\\\\\\\"lazy\\\\\\\" src=\\\\\\\"/docs-images/contacts/09.webp\\\\\\\" /\\u003e\\\\n\\u003cp\\u003eRemix sends a 405 because there is no code on the server to handle this form navigation.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"creating-contacts\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#creating-contacts\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eCreating Contacts\\u003c/h2\\u003e\\\\n\\u003cp\\u003eWe'll create new contacts by exporting an \\u003ccode\\u003eaction\\u003c/code\\u003e function in our root route. When the user clicks the \\\\\\\"new\\\\\\\" button, the form will \\u003ccode\\u003ePOST\\u003c/code\\u003e to the root route action.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eExport an \\u003ccode\\u003eaction\\u003c/code\\u003e function from \\u003ccode\\u003eapp/root.tsx\\u003c/code\\u003e\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/root.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/root.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(--base03)\\\\\\\"\\u003e// existing imports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ecreateEmptyContact\\u003c/span\\u003e, \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003egetContacts\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e./data\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eaction\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003easync\\u003c/span\\u003e () \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eawait\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ecreateEmptyContact\\u003c/span\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e };\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e};\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing code\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eThat's it! Go ahead and click the \\\\\\\"New\\\\\\\" button, and you should see a new record pop into the list 🥳\\u003c/p\\u003e\\\\n\\u003cimg class=\\\\\\\"tutorial\\\\\\\" loading=\\\\\\\"lazy\\\\\\\" src=\\\\\\\"/docs-images/contacts/11.webp\\\\\\\" /\\u003e\\\\n\\u003cp\\u003eThe \\u003ccode\\u003ecreateEmptyContact\\u003c/code\\u003e method just creates an empty contact with no name or data or anything. But it does still create a record, promise!\\u003c/p\\u003e\\\\n\\u003cblockquote\\u003e\\\\n\\u003cp\\u003e🧐 Wait a sec ... How did the sidebar update? Where did we call the \\u003ccode\\u003eaction\\u003c/code\\u003e function? Where's the code to re-fetch the data? Where are \\u003ccode\\u003euseState\\u003c/code\\u003e, \\u003ccode\\u003eonSubmit\\u003c/code\\u003e and \\u003ccode\\u003euseEffect\\u003c/code\\u003e?!\\u003c/p\\u003e\\\\n\\u003c/blockquote\\u003e\\\\n\\u003cp\\u003eThis is where the \\\\\\\"old school web\\\\\\\" programming model shows up. \\u003ca href=\\\\\\\"../components/form\\\\\\\"\\u003e\\u003ccode\\u003e\\u0026#x3C;Form\\u003e\\u003c/code\\u003e\\u003c/a\\u003e prevents the browser from sending the request to the server and sends it to your route's \\u003ccode\\u003eaction\\u003c/code\\u003e function instead with \\u003ca href=\\\\\\\"https://developer.mozilla.org/en-US/docs/Web/API/fetch\\\\\\\"\\u003e\\u003ccode\\u003efetch\\u003c/code\\u003e\\u003c/a\\u003e.\\u003c/p\\u003e\\\\n\\u003cp\\u003eIn web semantics, a \\u003ccode\\u003ePOST\\u003c/code\\u003e usually means some data is changing. By convention, Remix uses this as a hint to automatically revalidate the data on the page after the \\u003ccode\\u003eaction\\u003c/code\\u003e finishes.\\u003c/p\\u003e\\\\n\\u003cp\\u003eIn fact, since it's all just HTML and HTTP, you could disable JavaScript and the whole thing will still work. Instead of Remix serializing the form and making a \\u003ca href=\\\\\\\"https://developer.mozilla.org/en-US/docs/Web/API/fetch\\\\\\\"\\u003e\\u003ccode\\u003efetch\\u003c/code\\u003e\\u003c/a\\u003e request to your server, the browser will serialize the form and make a document request. From there Remix will render the page server side and send it down. It's the same UI in the end either way.\\u003c/p\\u003e\\\\n\\u003cp\\u003eWe'll keep JavaScript around, though, because we're going to make a better user experience than spinning favicons and static documents.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"updating-data\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#updating-data\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eUpdating Data\\u003c/h2\\u003e\\\\n\\u003cp\\u003eLet's add a way to fill the information for our new record.\\u003c/p\\u003e\\\\n\\u003cp\\u003eJust like creating data, you update data with \\u003ca href=\\\\\\\"../components/form\\\\\\\"\\u003e\\u003ccode\\u003e\\u0026#x3C;Form\\u003e\\u003c/code\\u003e\\u003c/a\\u003e. Let's make a new route at \\u003ccode\\u003eapp/routes/contacts.$contactId_.edit.tsx\\u003c/code\\u003e.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eCreate the edit component\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\"\\u003e\\u003cpre data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003etouch\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eapp/routes/contacts.\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0C)\\\\\\\"\\u003e\\\\\\\\$\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003econtactId_.edit.tsx\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eNote the weird \\u003ccode\\u003e_\\u003c/code\\u003e in \\u003ccode\\u003e$contactId_\\u003c/code\\u003e. By default, routes will automatically nest inside routes with the same prefixed name. Adding a trailing \\u003ccode\\u003e_\\u003c/code\\u003e tells the route to \\u003cstrong\\u003enot\\u003c/strong\\u003e nest inside \\u003ccode\\u003eapp/routes/contacts.$contactId.tsx\\u003c/code\\u003e. Read more in the \\u003ca href=\\\\\\\"../file-conventions/routes\\\\\\\"\\u003eRoute File Naming\\u003c/a\\u003e guide.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eAdd the edit page UI\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eNothing we haven't seen before, feel free to copy/paste:\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/routes/contacts.$contactId_.edit.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/routes/contacts.$contactId_.edit.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)\\\\\\\"\\u003eimport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etype\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eLoaderFunctionArgs\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/node\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eForm\\u003c/span\\u003e, \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003euseLoaderData\\u003c/span\\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=\\\\\\\"3\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003einvariant\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003etiny-invariant\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003egetContact\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e../data\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eloader\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003easync\\u003c/span\\u003e ({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e}\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eLoaderFunctionArgs\\u003c/span\\u003e) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003einvariant\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtactId\\u003c/span\\u003e, \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eMissing contactId param\\u003c/span\\u003e\\\\\\\");\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eawait\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003egetContact\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtactId\\u003c/span\\u003e);\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eif\\u003c/span\\u003e (\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e!\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e) {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ethrow\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003enew\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eResponse\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eNot Found\\u003c/span\\u003e\\\\\\\", { status: \\u003cspan style=\\\\\\\"color: var(--base09)\\\\\\\"\\u003e404\\u003c/span\\u003e });\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e }\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e };\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e};\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e\\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)\\\\\\\"\\u003eEditContact\\u003c/span\\u003e() {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseLoaderData\\u003c/span\\u003e\\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etypeof\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eloader\\u003c/span\\u003e\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"20\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"21\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"22\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ekey\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003econtact-form\\u003c/span\\u003e\\\\\\\" \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003emethod\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003epost\\u003c/span\\u003e\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"23\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ep\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"24\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003espan\\u003c/span\\u003e\\u003eName\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003espan\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"25\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003einput\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"26\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003earia-label\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eFirst name\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"27\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003edefaultValue\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efirst\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"28\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ename\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003efirst\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"29\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eplaceholder\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eFirst\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"30\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003etype\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003etext\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"31\\\\\\\"\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"32\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003einput\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"33\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003earia-label\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eLast name\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"34\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003edefaultValue\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003elast\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"35\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ename\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003elast\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"36\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eplaceholder\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eLast\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"37\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003etype\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003etext\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"38\\\\\\\"\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"39\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ep\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"40\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003elabel\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"41\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003espan\\u003c/span\\u003e\\u003eTwitter\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003espan\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"42\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003einput\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"43\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003edefaultValue\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003etwitter\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"44\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ename\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003etwitter\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"45\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eplaceholder\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@jack\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"46\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003etype\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003etext\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"47\\\\\\\"\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"48\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003elabel\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"49\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003elabel\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"50\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003espan\\u003c/span\\u003e\\u003eAvatar URL\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003espan\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"51\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003einput\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"52\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003earia-label\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eAvatar URL\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"53\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003edefaultValue\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eavatar\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"54\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ename\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eavatar\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"55\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eplaceholder\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003ehttps://example.com/avatar.jpg\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"56\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003etype\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003etext\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"57\\\\\\\"\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"58\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003elabel\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"59\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003elabel\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"60\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003espan\\u003c/span\\u003e\\u003eNotes\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003espan\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"61\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003etextarea\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"62\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003edefaultValue\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003enotes\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"63\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ename\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003enotes\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"64\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003erows\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base09)\\\\\\\"\\u003e6\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"65\\\\\\\"\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"66\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003elabel\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"67\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ep\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"68\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebutton\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003etype\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esubmit\\u003c/span\\u003e\\\\\\\"\\u003eSave\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebutton\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"69\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebutton\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003etype\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003ebutton\\u003c/span\\u003e\\\\\\\"\\u003eCancel\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebutton\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"70\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ep\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"71\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"72\\\\\\\"\\u003e );\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"73\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eNow click on your new record, then click the \\\\\\\"Edit\\\\\\\" button. We should see the new route.\\u003c/p\\u003e\\\\n\\u003cimg class=\\\\\\\"tutorial\\\\\\\" loading=\\\\\\\"lazy\\\\\\\" src=\\\\\\\"/docs-images/contacts/12.webp\\\\\\\" /\\u003e\\\\n\\u003ch2 id=\\\\\\\"updating-contacts-with-formdata\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#updating-contacts-with-formdata\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eUpdating Contacts with \\u003ccode\\u003eFormData\\u003c/code\\u003e\\u003c/h2\\u003e\\\\n\\u003cp\\u003eThe edit route we just created already renders a \\u003ccode\\u003eform\\u003c/code\\u003e. All we need to do is add the \\u003ccode\\u003eaction\\u003c/code\\u003e function. Remix will serialize the \\u003ccode\\u003eform\\u003c/code\\u003e, \\u003ccode\\u003ePOST\\u003c/code\\u003e it with \\u003ca href=\\\\\\\"https://developer.mozilla.org/en-US/docs/Web/API/fetch\\\\\\\"\\u003e\\u003ccode\\u003efetch\\u003c/code\\u003e\\u003c/a\\u003e, and automatically revalidate all the data.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eAdd an \\u003ccode\\u003eaction\\u003c/code\\u003e function to the edit route\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/routes/contacts.$contactId_.edit.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/routes/contacts.$contactId_.edit.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)\\\\\\\"\\u003eimport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etype\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eActionFunctionArgs\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eLoaderFunctionArgs\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e} \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/node\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eredirect\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/node\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing imports\\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-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003egetContact\\u003c/span\\u003e, \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eupdateContact\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e../data\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eaction\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003easync\\u003c/span\\u003e ({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003erequest\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e}\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eActionFunctionArgs\\u003c/span\\u003e) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003einvariant\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtactId\\u003c/span\\u003e, \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eMissing contactId param\\u003c/span\\u003e\\\\\\\");\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eformData\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eawait\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003erequest\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eformData\\u003c/span\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eupdates\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eObject\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003efromEntries\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eformData\\u003c/span\\u003e);\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eawait\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eupdateContact\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtactId\\u003c/span\\u003e, \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eupdates\\u003c/span\\u003e);\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eredirect\\u003c/span\\u003e(`\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e/contacts/\\u003c/span\\u003e${\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtactId\\u003c/span\\u003e}`);\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\u003e};\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"20\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"21\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing code\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eFill out the form, hit save, and you should see something like this! \\u003csmall\\u003e(Except easier on the eyes and maybe less hairy.)\\u003c/small\\u003e\\u003c/p\\u003e\\\\n\\u003cimg class=\\\\\\\"tutorial\\\\\\\" loading=\\\\\\\"lazy\\\\\\\" src=\\\\\\\"/docs-images/contacts/13.webp\\\\\\\" /\\u003e\\\\n\\u003ch2 id=\\\\\\\"mutation-discussion\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#mutation-discussion\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eMutation Discussion\\u003c/h2\\u003e\\\\n\\u003cblockquote\\u003e\\\\n\\u003cp\\u003e😑 It worked, but I have no idea what is going on here...\\u003c/p\\u003e\\\\n\\u003c/blockquote\\u003e\\\\n\\u003cp\\u003eLet's dig in a bit...\\u003c/p\\u003e\\\\n\\u003cp\\u003eOpen up \\u003ccode\\u003econtacts.$contactId_.edit.tsx\\u003c/code\\u003e and look at the \\u003ccode\\u003eform\\u003c/code\\u003e elements. Notice how they each have a name:\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/routes/contacts.$contactId_.edit.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/routes/contacts.$contactId_.edit.tsx\\\\\\\" 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(--base08)\\\\\\\"\\u003einput\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003earia-label\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eFirst name\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003edefaultValue\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efirst\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ename\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003efirst\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eplaceholder\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eFirst\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003etype\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003etext\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e/\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eWithout JavaScript, when a form is submitted, the browser will create \\u003ca href=\\\\\\\"https://developer.mozilla.org/en-US/docs/Web/API/FormData\\\\\\\"\\u003e\\u003ccode\\u003eFormData\\u003c/code\\u003e\\u003c/a\\u003e and set it as the body of the request when it sends it to the server. As mentioned before, Remix prevents that and emulates the browser by sending the request to your \\u003ccode\\u003eaction\\u003c/code\\u003e function with \\u003ca href=\\\\\\\"https://developer.mozilla.org/en-US/docs/Web/API/fetch\\\\\\\"\\u003e\\u003ccode\\u003efetch\\u003c/code\\u003e\\u003c/a\\u003e instead, including the \\u003ca href=\\\\\\\"https://developer.mozilla.org/en-US/docs/Web/API/FormData\\\\\\\"\\u003e\\u003ccode\\u003eFormData\\u003c/code\\u003e\\u003c/a\\u003e.\\u003c/p\\u003e\\\\n\\u003cp\\u003eEach field in the \\u003ccode\\u003eform\\u003c/code\\u003e is accessible with \\u003ccode\\u003eformData.get(name)\\u003c/code\\u003e. For example, given the input field from above, you could access the first and last names like this:\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/routes/contacts.$contactId_.edit.tsx\\\\\\\" data-nocopy=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/routes/contacts.$contactId_.edit.tsx\\\\\\\" data-nocopy=\\\\\\\"\\\\\\\" 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(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eaction\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003easync\\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(--base08)\\\\\\\"\\u003erequest\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e}\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eActionFunctionArgs\\u003c/span\\u003e) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eformData\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eawait\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003erequest\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eformData\\u003c/span\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efirstName\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eformData\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eget\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003efirst\\u003c/span\\u003e\\\\\\\");\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003elastName\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eformData\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eget\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003elast\\u003c/span\\u003e\\\\\\\");\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// ...\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e};\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eSince we have a handful of form fields, we used \\u003ca href=\\\\\\\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries\\\\\\\"\\u003e\\u003ccode\\u003eObject.fromEntries\\u003c/code\\u003e\\u003c/a\\u003e to collect them all into an object, which is exactly what our \\u003ccode\\u003eupdateContact\\u003c/code\\u003e function wants.\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/routes/contacts.$contactId_.edit.tsx\\\\\\\" data-nocopy=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/routes/contacts.$contactId_.edit.tsx\\\\\\\" data-nocopy=\\\\\\\"\\\\\\\" 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(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eupdates\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eObject\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003efromEntries\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eformData\\u003c/span\\u003e);\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eupdates\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efirst\\u003c/span\\u003e; \\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// \\\\\\\"Some\\\\\\\"\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eupdates\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003elast\\u003c/span\\u003e; \\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// \\\\\\\"Name\\\\\\\"\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eAside from the \\u003ccode\\u003eaction\\u003c/code\\u003e function, Remix provides none of these APIs we're discussing: \\u003ca href=\\\\\\\"https://developer.mozilla.org/en-US/docs/Web/API/Request\\\\\\\"\\u003e\\u003ccode\\u003erequest\\u003c/code\\u003e\\u003c/a\\u003e, \\u003ca href=\\\\\\\"https://developer.mozilla.org/en-US/docs/Web/API/Request/formData\\\\\\\"\\u003e\\u003ccode\\u003erequest.formData\\u003c/code\\u003e\\u003c/a\\u003e, \\u003ca href=\\\\\\\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries\\\\\\\"\\u003e\\u003ccode\\u003eObject.fromEntries\\u003c/code\\u003e\\u003c/a\\u003e are all provided by the web platform.\\u003c/p\\u003e\\\\n\\u003cp\\u003eAfter we finished the \\u003ccode\\u003eaction\\u003c/code\\u003e, note the \\u003ca href=\\\\\\\"../utils/redirect\\\\\\\"\\u003e\\u003ccode\\u003eredirect\\u003c/code\\u003e\\u003c/a\\u003e at the end:\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/routes/contacts.$contactId_.edit.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/routes/contacts.$contactId_.edit.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(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eaction\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003easync\\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(--base08)\\\\\\\"\\u003erequest\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e}\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eActionFunctionArgs\\u003c/span\\u003e) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003einvariant\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtactId\\u003c/span\\u003e, \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eMissing contactId param\\u003c/span\\u003e\\\\\\\");\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eformData\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eawait\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003erequest\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eformData\\u003c/span\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eupdates\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eObject\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003efromEntries\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eformData\\u003c/span\\u003e);\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eawait\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eupdateContact\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtactId\\u003c/span\\u003e, \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eupdates\\u003c/span\\u003e);\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eredirect\\u003c/span\\u003e(`\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e/contacts/\\u003c/span\\u003e${\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtactId\\u003c/span\\u003e}`);\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e};\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e\\u003ccode\\u003eaction\\u003c/code\\u003e and \\u003ccode\\u003eloader\\u003c/code\\u003e functions can both \\u003ca href=\\\\\\\"../route/loader#returning-response-instances\\\\\\\"\\u003ereturn a \\u003ccode\\u003eResponse\\u003c/code\\u003e\\u003c/a\\u003e (makes sense, since they received a \\u003ca href=\\\\\\\"https://developer.mozilla.org/en-US/docs/Web/API/Request\\\\\\\"\\u003e\\u003ccode\\u003eRequest\\u003c/code\\u003e\\u003c/a\\u003e!). The \\u003ca href=\\\\\\\"../utils/redirect\\\\\\\"\\u003e\\u003ccode\\u003eredirect\\u003c/code\\u003e\\u003c/a\\u003e helper just makes it easier to return a \\u003ca href=\\\\\\\"https://developer.mozilla.org/en-US/docs/Web/API/Response\\\\\\\"\\u003e\\u003ccode\\u003eResponse\\u003c/code\\u003e\\u003c/a\\u003e that tells the app to change locations.\\u003c/p\\u003e\\\\n\\u003cp\\u003eWithout client side routing, if a server redirected after a \\u003ccode\\u003ePOST\\u003c/code\\u003e request, the new page would fetch the latest data and render. As we learned before, Remix emulates this model and automatically revalidates the data on the page after the \\u003ccode\\u003eaction\\u003c/code\\u003e call. That's why the sidebar automatically updates when we save the form. The extra revalidation code doesn't exist without client side routing, so it doesn't need to exist with client side routing in Remix either!\\u003c/p\\u003e\\\\n\\u003cp\\u003eOne last thing. Without JavaScript, the \\u003ca href=\\\\\\\"../utils/redirect\\\\\\\"\\u003e\\u003ccode\\u003eredirect\\u003c/code\\u003e\\u003c/a\\u003e would be a normal redirect. However, with JavaScript it's a client-side redirect, so the user doesn't lose client state like scroll positions or component state.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"redirecting-new-records-to-the-edit-page\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#redirecting-new-records-to-the-edit-page\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eRedirecting new records to the edit page\\u003c/h2\\u003e\\\\n\\u003cp\\u003eNow that we know how to redirect, let's update the action that creates new contacts to redirect to the edit page:\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eRedirect to the new record's edit page\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/root.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/root.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(--base03)\\\\\\\"\\u003e// existing imports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eredirect\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/node\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing imports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eaction\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003easync\\u003c/span\\u003e () \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eawait\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ecreateEmptyContact\\u003c/span\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eredirect\\u003c/span\\u003e(`\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e/contacts/\\u003c/span\\u003e${\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eid\\u003c/span\\u003e}\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e/edit\\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\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing code\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eNow when we click \\\\\\\"New\\\\\\\", we should end up on the edit page:\\u003c/p\\u003e\\\\n\\u003cimg class=\\\\\\\"tutorial\\\\\\\" loading=\\\\\\\"lazy\\\\\\\" src=\\\\\\\"/docs-images/contacts/14.webp\\\\\\\" /\\u003e\\\\n\\u003ch2 id=\\\\\\\"active-link-styling\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#active-link-styling\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eActive Link Styling\\u003c/h2\\u003e\\\\n\\u003cp\\u003eNow that we have a bunch of records, it's not clear which one we're looking at in the sidebar. We can use \\u003ca href=\\\\\\\"../components/nav-link\\\\\\\"\\u003e\\u003ccode\\u003eNavLink\\u003c/code\\u003e\\u003c/a\\u003e to fix this.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eReplace \\u003ccode\\u003e\\u0026#x3C;Link\\u003e\\u003c/code\\u003e with \\u003ccode\\u003e\\u0026#x3C;NavLink\\u003e\\u003c/code\\u003e in the sidebar\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/root.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/root.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(--base03)\\\\\\\"\\u003e// existing imports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eForm\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eLinks\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eMeta\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eNavLink\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eOutlet\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eScripts\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eScrollRestoration\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003euseLoaderData\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\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=\\\\\\\"12\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing imports and exports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\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)\\\\\\\"\\u003eApp\\u003c/span\\u003e() {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtacts\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseLoaderData\\u003c/span\\u003e\\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etypeof\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eloader\\u003c/span\\u003e\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\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=\\\\\\\"20\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"21\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"22\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esidebar\\u003c/span\\u003e\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"23\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"24\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eul\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"25\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtacts\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003emap\\u003c/span\\u003e((\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"26\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eli\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ekey\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"27\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eNavLink\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"28\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eclassName\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e({ \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eisActive\\u003c/span\\u003e, \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eisPending\\u003c/span\\u003e }) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"29\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eisActive\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"30\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e?\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eactive\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"31\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eisPending\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"32\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e?\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003epending\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"33\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\\\\\\"\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"34\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"35\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eto\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e`\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003econtacts/\\u003c/span\\u003e${\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eid\\u003c/span\\u003e}`\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"36\\\\\\\"\\u003e \\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"37\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"38\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eNavLink\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"39\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eli\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"40\\\\\\\"\\u003e ))\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"41\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eul\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"42\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"43\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"44\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"45\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"46\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ehtml\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"47\\\\\\\"\\u003e );\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"48\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eNote that we are passing a function to \\u003ccode\\u003eclassName\\u003c/code\\u003e. When the user is at the URL that matches \\u003ccode\\u003e\\u0026#x3C;NavLink to\\u003e\\u003c/code\\u003e, then \\u003ccode\\u003eisActive\\u003c/code\\u003e will be true. When it's \\u003cem\\u003eabout\\u003c/em\\u003e to be active (the data is still loading) then \\u003ccode\\u003eisPending\\u003c/code\\u003e will be true. This allows us to easily indicate where the user is and also provide immediate when links are clicked, but data needs to be loaded.\\u003c/p\\u003e\\\\n\\u003cimg class=\\\\\\\"tutorial\\\\\\\" loading=\\\\\\\"lazy\\\\\\\" src=\\\\\\\"/docs-images/contacts/15.webp\\\\\\\"/\\u003e\\\\n\\u003ch2 id=\\\\\\\"global-pending-ui\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#global-pending-ui\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eGlobal Pending UI\\u003c/h2\\u003e\\\\n\\u003cp\\u003eAs the user navigates the app, Remix will \\u003cem\\u003eleave the old page up\\u003c/em\\u003e as data is loading for the next page. You may have noticed the app feels a little unresponsive as you click between the list. Let's provide the user with some so the app doesn't feel unresponsive.\\u003c/p\\u003e\\\\n\\u003cp\\u003eRemix is managing all the states behind the scenes and reveals the pieces you need to build dynamic web apps. In this case, we'll use the \\u003ca href=\\\\\\\"../hooks/use-navigation\\\\\\\"\\u003e\\u003ccode\\u003euseNavigation\\u003c/code\\u003e\\u003c/a\\u003e hook.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eUse \\u003ccode\\u003euseNavigation\\u003c/code\\u003e to add global pending UI\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/root.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/root.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(--base03)\\\\\\\"\\u003e// existing imports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eForm\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eLinks\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eMeta\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eNavLink\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eOutlet\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eScripts\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eScrollRestoration\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003euseLoaderData\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003euseNavigation\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\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=\\\\\\\"13\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing imports and exports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e\\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)\\\\\\\"\\u003eApp\\u003c/span\\u003e() {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtacts\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseLoaderData\\u003c/span\\u003e\\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etypeof\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eloader\\u003c/span\\u003e\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003enavigation\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseNavigation\\u003c/span\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"20\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\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 \\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=\\\\\\\"22\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"23\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"24\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"25\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"26\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eclassName\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"27\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003enavigation\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003estate\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e===\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eloading\\u003c/span\\u003e\\\\\\\" \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e?\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eloading\\u003c/span\\u003e\\\\\\\" \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\\\\\\"\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"28\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"29\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003edetail\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"30\\\\\\\"\\u003e \\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"31\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eOutlet\\u003c/span\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"32\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"33\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"34\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"35\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ehtml\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"36\\\\\\\"\\u003e );\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"37\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e\\u003ca href=\\\\\\\"../hooks/use-navigation\\\\\\\"\\u003e\\u003ccode\\u003euseNavigation\\u003c/code\\u003e\\u003c/a\\u003e returns the current navigation state: it can be one of \\u003ccode\\u003e\\\\\\\"idle\\\\\\\"\\u003c/code\\u003e, \\u003ccode\\u003e\\\\\\\"loading\\\\\\\"\\u003c/code\\u003e or \\u003ccode\\u003e\\\\\\\"submitting\\\\\\\"\\u003c/code\\u003e.\\u003c/p\\u003e\\\\n\\u003cp\\u003eIn our case, we add a \\u003ccode\\u003e\\\\\\\"loading\\\\\\\"\\u003c/code\\u003e class to the main part of the app if we're not idle. The CSS then adds a nice fade after a short delay (to avoid flickering the UI for fast loads). You could do anything you want, though, like show a spinner or loading bar across the top.\\u003c/p\\u003e\\\\n\\u003cimg class=\\\\\\\"tutorial\\\\\\\" loading=\\\\\\\"lazy\\\\\\\" src=\\\\\\\"/docs-images/contacts/16.webp\\\\\\\" /\\u003e\\\\n\\u003ch2 id=\\\\\\\"deleting-records\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#deleting-records\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eDeleting Records\\u003c/h2\\u003e\\\\n\\u003cp\\u003eIf we review code in the contact route, we can find the delete button looks like this:\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/routes/contact.$contactId.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/routes/contact.$contactId.tsx\\\\\\\" 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)\\\\\\\"\\u003eForm\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eaction\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003edestroy\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003emethod\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003epost\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eonSubmit\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eevent\\u003c/span\\u003e) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eresponse\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003econfirm\\u003c/span\\u003e(\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003ePlease confirm you want to delete this record.\\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 \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eif\\u003c/span\\u003e (\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e!\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eresponse\\u003c/span\\u003e) {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eevent\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003epreventDefault\\u003c/span\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e }\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e }\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebutton\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003etype\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esubmit\\u003c/span\\u003e\\\\\\\"\\u003eDelete\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebutton\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eNote the \\u003ccode\\u003eaction\\u003c/code\\u003e points to \\u003ccode\\u003e\\\\\\\"destroy\\\\\\\"\\u003c/code\\u003e. Like \\u003ccode\\u003e\\u0026#x3C;Link to\\u003e\\u003c/code\\u003e, \\u003ccode\\u003e\\u0026#x3C;Form action\\u003e\\u003c/code\\u003e can take a \\u003cem\\u003erelative\\u003c/em\\u003e value. Since the form is rendered in \\u003ccode\\u003econtacts.$contactId.tsx\\u003c/code\\u003e, then a relative action with \\u003ccode\\u003edestroy\\u003c/code\\u003e will submit the form to \\u003ccode\\u003econtacts.$contactId.destroy\\u003c/code\\u003e when clicked.\\u003c/p\\u003e\\\\n\\u003cp\\u003eAt this point you should know everything you need to know to make the delete button work. Maybe give it a try before moving on? You'll need:\\u003c/p\\u003e\\\\n\\u003col\\u003e\\\\n\\u003cli\\u003eA new route\\u003c/li\\u003e\\\\n\\u003cli\\u003eAn \\u003ccode\\u003eaction\\u003c/code\\u003e at that route\\u003c/li\\u003e\\\\n\\u003cli\\u003e\\u003ccode\\u003edeleteContact\\u003c/code\\u003e from \\u003ccode\\u003eapp/data.ts\\u003c/code\\u003e\\u003c/li\\u003e\\\\n\\u003cli\\u003e\\u003ccode\\u003eredirect\\u003c/code\\u003e to somewhere after\\u003c/li\\u003e\\\\n\\u003c/ol\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eCreate the \\\\\\\"destroy\\\\\\\" route module\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\"\\u003e\\u003cpre data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003etouch\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eapp/routes/contacts.\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0C)\\\\\\\"\\u003e\\\\\\\\$\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003econtactId_.destroy.tsx\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eAdd the destroy action\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/routes/contacts.$contactId_.destroy.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/routes/contacts.$contactId_.destroy.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)\\\\\\\"\\u003eimport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etype\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eActionFunctionArgs\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/node\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eredirect\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/node\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003einvariant\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003etiny-invariant\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003edeleteContact\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e../data\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eaction\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003easync\\u003c/span\\u003e ({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e}\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eActionFunctionArgs\\u003c/span\\u003e) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003einvariant\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtactId\\u003c/span\\u003e, \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eMissing contactId param\\u003c/span\\u003e\\\\\\\");\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eawait\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003edeleteContact\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtactId\\u003c/span\\u003e);\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eredirect\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e/\\u003c/span\\u003e\\\\\\\");\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e};\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eAlright, navigate to a record and click the \\\\\\\"Delete\\\\\\\" button. It works!\\u003c/p\\u003e\\\\n\\u003cblockquote\\u003e\\\\n\\u003cp\\u003e😅 I'm still confused why this all works\\u003c/p\\u003e\\\\n\\u003c/blockquote\\u003e\\\\n\\u003cp\\u003eWhen the user clicks the submit button:\\u003c/p\\u003e\\\\n\\u003col\\u003e\\\\n\\u003cli\\u003e\\u003ccode\\u003e\\u0026#x3C;Form\\u003e\\u003c/code\\u003e prevents the default browser behavior of sending a new document \\u003ccode\\u003ePOST\\u003c/code\\u003e request to the server, but instead emulates the browser by creating a \\u003ccode\\u003ePOST\\u003c/code\\u003e request with client side routing and \\u003ca href=\\\\\\\"https://developer.mozilla.org/en-US/docs/Web/API/fetch\\\\\\\"\\u003e\\u003ccode\\u003efetch\\u003c/code\\u003e\\u003c/a\\u003e\\u003c/li\\u003e\\\\n\\u003cli\\u003eThe \\u003ccode\\u003e\\u0026#x3C;Form action=\\\\\\\"destroy\\\\\\\"\\u003e\\u003c/code\\u003e matches the new route at \\u003ccode\\u003econtacts.$contactId_.destroy.tsx\\u003c/code\\u003e and sends it the request\\u003c/li\\u003e\\\\n\\u003cli\\u003eAfter the \\u003ccode\\u003eaction\\u003c/code\\u003e redirects, Remix calls all the \\u003ccode\\u003eloader\\u003c/code\\u003es for the data on the page to get the latest values (this is \\\\\\\"revalidation\\\\\\\"). \\u003ccode\\u003euseLoaderData\\u003c/code\\u003e returns new values and causes the components to update!\\u003c/li\\u003e\\\\n\\u003c/ol\\u003e\\\\n\\u003cp\\u003eAdd a \\u003ccode\\u003eForm\\u003c/code\\u003e, add an \\u003ccode\\u003eaction\\u003c/code\\u003e, Remix does the rest.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"index-routes\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#index-routes\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eIndex Routes\\u003c/h2\\u003e\\\\n\\u003cp\\u003eWhen we load up the app, you'll notice a big blank page on the right side of our list.\\u003c/p\\u003e\\\\n\\u003cimg class=\\\\\\\"tutorial\\\\\\\" loading=\\\\\\\"lazy\\\\\\\" src=\\\\\\\"/docs-images/contacts/17.webp\\\\\\\" /\\u003e\\\\n\\u003cp\\u003eWhen a route has children, and you're at the parent route's path, the \\u003ccode\\u003e\\u0026#x3C;Outlet\\u003e\\u003c/code\\u003e has nothing to render because no children match. You can think of index routes as the default child route to fill in that space.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eCreate an index route for the root route\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\"\\u003e\\u003cpre data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003etouch\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eapp/routes/_index.tsx\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eFill in the index component's elements\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eFeel free to copy/paste, nothing special here.\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/routes/_index.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/routes/_index.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)\\\\\\\"\\u003edefault\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003efunction\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eIndex\\u003c/span\\u003e() {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ep\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eindex-page\\u003c/span\\u003e\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e This is a demo for Remix.\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebr\\u003c/span\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e Check out\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e \\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ea\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ehref\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003ehttps://remix.run\\u003c/span\\u003e\\\\\\\"\\u003ethe docs at remix.run\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ea\\u003c/span\\u003e\\u003e.\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ep\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e );\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eThe route name \\u003ccode\\u003e_index\\u003c/code\\u003e is special. It tells Remix to match and render this route when the user is at the parent route's exact path, so there are no other child routes to render in the \\u003ccode\\u003e\\u0026#x3C;Outlet /\\u003e\\u003c/code\\u003e.\\u003c/p\\u003e\\\\n\\u003cimg class=\\\\\\\"tutorial\\\\\\\" loading=\\\\\\\"lazy\\\\\\\" src=\\\\\\\"/docs-images/contacts/18.webp\\\\\\\" /\\u003e\\\\n\\u003cp\\u003eVoilà! No more blank space. It's common to put dashboards, stats, feeds, etc. at index routes. They can participate in data loading as well.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"cancel-button\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#cancel-button\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eCancel Button\\u003c/h2\\u003e\\\\n\\u003cp\\u003eOn the edit page we've got a cancel button that doesn't do anything yet. We'd like it to do the same thing as the browser's back button.\\u003c/p\\u003e\\\\n\\u003cp\\u003eWe'll need a click handler on the button as well as \\u003ca href=\\\\\\\"../hooks/use-navigate\\\\\\\"\\u003e\\u003ccode\\u003euseNavigate\\u003c/code\\u003e\\u003c/a\\u003e.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eAdd the cancel button click handler with \\u003ccode\\u003euseNavigate\\u003c/code\\u003e\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/routes/contacts.$contactId_.edit.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/routes/contacts.$contactId_.edit.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(--base03)\\\\\\\"\\u003e// existing imports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eForm\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003euseLoaderData\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003euseNavigate\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\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=\\\\\\\"7\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing imports and exports\\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)\\\\\\\"\\u003eEditContact\\u003c/span\\u003e() {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseLoaderData\\u003c/span\\u003e\\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etypeof\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eloader\\u003c/span\\u003e\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003enavigate\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseNavigate\\u003c/span\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ekey\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003econtact-form\\u003c/span\\u003e\\\\\\\" \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003emethod\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003epost\\u003c/span\\u003e\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ep\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebutton\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003etype\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esubmit\\u003c/span\\u003e\\\\\\\"\\u003eSave\\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebutton\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebutton\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eonClick\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e() \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003enavigate\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e-\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base09)\\\\\\\"\\u003e1\\u003c/span\\u003e)\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003etype\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003ebutton\\u003c/span\\u003e\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\u003e Cancel\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"20\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebutton\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"21\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ep\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"22\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"23\\\\\\\"\\u003e );\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"24\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eNow when the user clicks \\\\\\\"Cancel\\\\\\\", they'll be sent back one entry in the browser's history.\\u003c/p\\u003e\\\\n\\u003cblockquote\\u003e\\\\n\\u003cp\\u003e🧐 Why is there no \\u003ccode\\u003eevent.preventDefault()\\u003c/code\\u003e on the button?\\u003c/p\\u003e\\\\n\\u003c/blockquote\\u003e\\\\n\\u003cp\\u003eA \\u003ccode\\u003e\\u0026#x3C;button type=\\\\\\\"button\\\\\\\"\\u003e\\u003c/code\\u003e, while seemingly redundant, is the HTML way of preventing a button from submitting its form.\\u003c/p\\u003e\\\\n\\u003cp\\u003eTwo more features to go. We're on the home stretch!\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"urlsearchparams-and-get-submissions\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#urlsearchparams-and-get-submissions\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003e\\u003ccode\\u003eURLSearchParams\\u003c/code\\u003e and \\u003ccode\\u003eGET\\u003c/code\\u003e Submissions\\u003c/h2\\u003e\\\\n\\u003cp\\u003eAll of our interactive UI so far have been either links that change the URL or \\u003ccode\\u003eform\\u003c/code\\u003es that post data to \\u003ccode\\u003eaction\\u003c/code\\u003e functions. The search field is interesting because it's a mix of both: it's a \\u003ccode\\u003eform\\u003c/code\\u003e, but it only changes the URL, it doesn't change data.\\u003c/p\\u003e\\\\n\\u003cp\\u003eLet's see what happens when we submit the search form:\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eType a name into the search field and hit the enter key\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eNote the browser's URL now contains your query in the URL as \\u003ca href=\\\\\\\"https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams\\\\\\\"\\u003e\\u003ccode\\u003eURLSearchParams\\u003c/code\\u003e\\u003c/a\\u003e:\\u003c/p\\u003e\\\\n\\u003cpre\\u003e\\u003ccode\\u003ehttp://localhost:5173/?q=ryan\\\\n\\u003c/code\\u003e\\u003c/pre\\u003e\\\\n\\u003cp\\u003eSince it's not \\u003ccode\\u003e\\u0026#x3C;Form method=\\\\\\\"post\\\\\\\"\\u003e\\u003c/code\\u003e, Remix emulates the browser by serializing the \\u003ca href=\\\\\\\"https://developer.mozilla.org/en-US/docs/Web/API/FormData\\\\\\\"\\u003e\\u003ccode\\u003eFormData\\u003c/code\\u003e\\u003c/a\\u003e into the \\u003ca href=\\\\\\\"https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams\\\\\\\"\\u003e\\u003ccode\\u003eURLSearchParams\\u003c/code\\u003e\\u003c/a\\u003e instead of the request body.\\u003c/p\\u003e\\\\n\\u003cp\\u003e\\u003ccode\\u003eloader\\u003c/code\\u003e functions have access to the search params from the \\u003ccode\\u003erequest\\u003c/code\\u003e. Let's use it to filter the list:\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eFilter the list if there are \\u003ccode\\u003eURLSearchParams\\u003c/code\\u003e\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/root.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/root.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)\\\\\\\"\\u003eimport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etype\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eLinksFunction\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eLoaderFunctionArgs\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e} \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/node\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing imports and exports\\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-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eloader\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003easync\\u003c/span\\u003e ({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003erequest\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e}\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eLoaderFunctionArgs\\u003c/span\\u003e) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eurl\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003enew\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eURL\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003erequest\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eurl\\u003c/span\\u003e);\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eq\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eurl\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003esearchParams\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eget\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eq\\u003c/span\\u003e\\\\\\\");\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtacts\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eawait\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003egetContacts\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eq\\u003c/span\\u003e);\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtacts\\u003c/span\\u003e };\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e};\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing code\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cimg class=\\\\\\\"tutorial\\\\\\\" loading=\\\\\\\"lazy\\\\\\\" src=\\\\\\\"/docs-images/contacts/19.webp\\\\\\\" /\\u003e\\\\n\\u003cp\\u003eBecause this is a \\u003ccode\\u003eGET\\u003c/code\\u003e, not a \\u003ccode\\u003ePOST\\u003c/code\\u003e, Remix \\u003cem\\u003edoes not\\u003c/em\\u003e call the \\u003ccode\\u003eaction\\u003c/code\\u003e function. Submitting a \\u003ccode\\u003eGET\\u003c/code\\u003e \\u003ccode\\u003eform\\u003c/code\\u003e is the same as clicking a link: only the URL changes.\\u003c/p\\u003e\\\\n\\u003cp\\u003eThis also means it's a normal page navigation. You can click the back button to get back to where you were.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"synchronizing-urls-to-form-state\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#synchronizing-urls-to-form-state\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eSynchronizing URLs to Form State\\u003c/h2\\u003e\\\\n\\u003cp\\u003eThere are a couple of UX issues here that we can take care of quickly.\\u003c/p\\u003e\\\\n\\u003col\\u003e\\\\n\\u003cli\\u003eIf you click back after a search, the form field still has the value you entered even though the list is no longer filtered.\\u003c/li\\u003e\\\\n\\u003cli\\u003eIf you refresh the page after searching, the form field no longer has the value in it, even though the list is filtered\\u003c/li\\u003e\\\\n\\u003c/ol\\u003e\\\\n\\u003cp\\u003eIn other words, the URL and our input's state are out of sync.\\u003c/p\\u003e\\\\n\\u003cp\\u003eLet's solve (2) first and start the input with the value from the URL.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eReturn \\u003ccode\\u003eq\\u003c/code\\u003e from your \\u003ccode\\u003eloader\\u003c/code\\u003e, set it as the input's default value\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/root.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/root.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(--base03)\\\\\\\"\\u003e// existing imports and exports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eloader\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003easync\\u003c/span\\u003e ({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003erequest\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e}\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eLoaderFunctionArgs\\u003c/span\\u003e) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eurl\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003enew\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eURL\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003erequest\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eurl\\u003c/span\\u003e);\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eq\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eurl\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003esearchParams\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eget\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eq\\u003c/span\\u003e\\\\\\\");\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtacts\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eawait\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003egetContacts\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eq\\u003c/span\\u003e);\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtacts\\u003c/span\\u003e, \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eq\\u003c/span\\u003e };\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e};\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\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)\\\\\\\"\\u003eApp\\u003c/span\\u003e() {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtacts\\u003c/span\\u003e, \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eq\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseLoaderData\\u003c/span\\u003e\\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etypeof\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eloader\\u003c/span\\u003e\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003enavigation\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseNavigation\\u003c/span\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\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=\\\\\\\"18\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"20\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esidebar\\u003c/span\\u003e\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"21\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"22\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"23\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esearch-form\\u003c/span\\u003e\\\\\\\" \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003erole\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esearch\\u003c/span\\u003e\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"24\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003einput\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"25\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003earia-label\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eSearch contacts\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"26\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003edefaultValue\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eq\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e||\\u003c/span\\u003e \\\\\\\"\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"27\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eq\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"28\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ename\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eq\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"29\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eplaceholder\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eSearch\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"30\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003etype\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esearch\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"31\\\\\\\"\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"32\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"33\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"34\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"35\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"36\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"37\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"38\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"39\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"40\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ehtml\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"41\\\\\\\"\\u003e );\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"42\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eThe input field will show the query if you refresh the page after a search now.\\u003c/p\\u003e\\\\n\\u003cp\\u003eNow for problem (1), clicking the back button and updating the input. We can bring in \\u003ccode\\u003euseEffect\\u003c/code\\u003e from React to manipulate the input's value in the DOM directly.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eSynchronize input value with the \\u003ccode\\u003eURLSearchParams\\u003c/code\\u003e\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/root.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/root.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(--base03)\\\\\\\"\\u003e// existing imports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003euseEffect\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003ereact\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing imports and exports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\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)\\\\\\\"\\u003eApp\\u003c/span\\u003e() {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtacts\\u003c/span\\u003e, \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eq\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseLoaderData\\u003c/span\\u003e\\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etypeof\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eloader\\u003c/span\\u003e\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003enavigation\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseNavigation\\u003c/span\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseEffect\\u003c/span\\u003e(() \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003esearchField\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003edocument\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003egetElementById\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eq\\u003c/span\\u003e\\\\\\\");\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eif\\u003c/span\\u003e (\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003esearchField\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003einstanceof\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eHTMLInputElement\\u003c/span\\u003e) {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003esearchField\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003evalue\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eq\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e||\\u003c/span\\u003e \\\\\\\"\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e }\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e }, [\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eq\\u003c/span\\u003e]);\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing code\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cblockquote\\u003e\\\\n\\u003cp\\u003e🤔 Shouldn't you use a controlled component and React State for this?\\u003c/p\\u003e\\\\n\\u003c/blockquote\\u003e\\\\n\\u003cp\\u003eYou could certainly do this as a controlled component. You will have more synchronization points, but it's up to you.\\u003c/p\\u003e\\\\n\\u003cdetails\\u003e\\\\n\\u003csummary\\u003eExpand this to see what it would look like\\u003c/summary\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/root.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/root.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(--base03)\\\\\\\"\\u003e// We no longer need useEffect\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003euseState\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003ereact\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing imports and exports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\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)\\\\\\\"\\u003eApp\\u003c/span\\u003e() {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtacts\\u003c/span\\u003e, \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eq\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseLoaderData\\u003c/span\\u003e\\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etypeof\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eloader\\u003c/span\\u003e\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003enavigation\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseNavigation\\u003c/span\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// the query now needs to be kept in state\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e [\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eprevQ\\u003c/span\\u003e, \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003esetPrevQ\\u003c/span\\u003e] \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseState\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eq\\u003c/span\\u003e);\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e [\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003equery\\u003c/span\\u003e, \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003esetQuery\\u003c/span\\u003e] \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseState\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eq\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e||\\u003c/span\\u003e \\\\\\\"\\\\\\\");\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// We can avoid using `useEffect` to synchronize the query\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// by using a separate piece of state to store the previous\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// value\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eif\\u003c/span\\u003e (\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eq\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e!==\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eprevQ\\u003c/span\\u003e) {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003esetPrevQ\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eq\\u003c/span\\u003e);\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003esetQuery\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eq\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e||\\u003c/span\\u003e \\\\\\\"\\\\\\\");\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\u003e }\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"20\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"21\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"22\\\\\\\"\\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=\\\\\\\"23\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"24\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"25\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esidebar\\u003c/span\\u003e\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"26\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"27\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"28\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esearch-form\\u003c/span\\u003e\\\\\\\" \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003erole\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esearch\\u003c/span\\u003e\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"29\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003einput\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"30\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003earia-label\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eSearch contacts\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"31\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eq\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"32\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ename\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eq\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"33\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// synchronize user's input to component state\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"34\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eonChange\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eevent\\u003c/span\\u003e) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"35\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003esetQuery\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eevent\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ecurrentTarget\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003evalue\\u003c/span\\u003e)\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"36\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"37\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eplaceholder\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eSearch\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"38\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003etype\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esearch\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"39\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// switched to `value` from `defaultValue`\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"40\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003evalue\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003equery\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"41\\\\\\\"\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"42\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"43\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"44\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"45\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"46\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"47\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"48\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"49\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"50\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ehtml\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"51\\\\\\\"\\u003e );\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"52\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003c/details\\u003e\\\\n\\u003cp\\u003eAlright, you should now be able to click the back/forward/refresh buttons, and the input's value should be in sync with the URL and results.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"submitting-forms-onchange\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#submitting-forms-onchange\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eSubmitting \\u003ccode\\u003eForm\\u003c/code\\u003e's \\u003ccode\\u003eonChange\\u003c/code\\u003e\\u003c/h2\\u003e\\\\n\\u003cp\\u003eWe've got a product decision to make here. Sometimes you want the user to submit the \\u003ccode\\u003eform\\u003c/code\\u003e to filter some results, other times you want to filter as the user types. We've already implemented the first, so let's see what it's like for the second.\\u003c/p\\u003e\\\\n\\u003cp\\u003eWe've seen \\u003ccode\\u003euseNavigate\\u003c/code\\u003e already, we'll use its cousin, \\u003ca href=\\\\\\\"../hooks/use-submit\\\\\\\"\\u003e\\u003ccode\\u003euseSubmit\\u003c/code\\u003e\\u003c/a\\u003e, for this.\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/root.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/root.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(--base03)\\\\\\\"\\u003e// existing imports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eForm\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eLinks\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eMeta\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eNavLink\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eOutlet\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eScripts\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eScrollRestoration\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003euseLoaderData\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003euseNavigation\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003euseSubmit\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\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=\\\\\\\"14\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing imports and exports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e\\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)\\\\\\\"\\u003eApp\\u003c/span\\u003e() {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtacts\\u003c/span\\u003e, \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eq\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseLoaderData\\u003c/span\\u003e\\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etypeof\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eloader\\u003c/span\\u003e\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003enavigation\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseNavigation\\u003c/span\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003esubmit\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseSubmit\\u003c/span\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"20\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"21\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing code\\u003c/span\\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 \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"24\\\\\\\"\\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=\\\\\\\"25\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"26\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"27\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esidebar\\u003c/span\\u003e\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"28\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"29\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"30\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"31\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esearch-form\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"32\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eonChange\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eevent\\u003c/span\\u003e) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"33\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003esubmit\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eevent\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ecurrentTarget\\u003c/span\\u003e)\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"34\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"35\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003erole\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esearch\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"36\\\\\\\"\\u003e \\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"37\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"38\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"39\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"40\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"41\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"42\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"43\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"44\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"45\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ehtml\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"46\\\\\\\"\\u003e );\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"47\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eAs you type, the \\u003ccode\\u003eform\\u003c/code\\u003e is automatically submitted now!\\u003c/p\\u003e\\\\n\\u003cp\\u003eNote the argument to \\u003ca href=\\\\\\\"../hooks/use-submit\\\\\\\"\\u003e\\u003ccode\\u003esubmit\\u003c/code\\u003e\\u003c/a\\u003e. The \\u003ccode\\u003esubmit\\u003c/code\\u003e function will serialize and submit any form you pass to it. We're passing in \\u003ccode\\u003eevent.currentTarget\\u003c/code\\u003e. The \\u003ccode\\u003ecurrentTarget\\u003c/code\\u003e is the DOM node the event is attached to (the \\u003ccode\\u003eform\\u003c/code\\u003e).\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"adding-search-spinner\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#adding-search-spinner\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eAdding Search Spinner\\u003c/h2\\u003e\\\\n\\u003cp\\u003eIn a production app, it's likely this search will be looking for records in a database that is too large to send all at once and filter client side. That's why this demo has some faked network latency.\\u003c/p\\u003e\\\\n\\u003cp\\u003eWithout any loading indicator, the search feels kinda sluggish. Even if we could make our database faster, we'll always have the user's network latency in the way and out of our control.\\u003c/p\\u003e\\\\n\\u003cp\\u003eFor a better user experience, let's add some immediate UI for the search. We'll use \\u003ca href=\\\\\\\"../hooks/use-navigation\\\\\\\"\\u003e\\u003ccode\\u003euseNavigation\\u003c/code\\u003e\\u003c/a\\u003e again.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eAdd a variable to know if we're searching\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/root.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/root.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(--base03)\\\\\\\"\\u003e// existing imports and exports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\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)\\\\\\\"\\u003eApp\\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)\\\\\\\"\\u003econtacts\\u003c/span\\u003e, \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eq\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseLoaderData\\u003c/span\\u003e\\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etypeof\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eloader\\u003c/span\\u003e\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003enavigation\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseNavigation\\u003c/span\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003esubmit\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseSubmit\\u003c/span\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003esearching\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003enavigation\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003elocation\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e\\u0026#x26;\\u0026#x26;\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003enew\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eURLSearchParams\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003enavigation\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003elocation\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003esearch\\u003c/span\\u003e).\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ehas\\u003c/span\\u003e(\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eq\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e );\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing code\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eWhen nothing is happening, \\u003ccode\\u003enavigation.location\\u003c/code\\u003e will be \\u003ccode\\u003eundefined\\u003c/code\\u003e, but when the user navigates it will be populated with the next location while data loads. Then we check if they're searching with \\u003ccode\\u003elocation.search\\u003c/code\\u003e.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eAdd classes to search form elements using the new \\u003ccode\\u003esearching\\u003c/code\\u003e state\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/root.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/root.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(--base03)\\\\\\\"\\u003e// existing imports and exports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\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)\\\\\\\"\\u003eApp\\u003c/span\\u003e() {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing code\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\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=\\\\\\\"8\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esidebar\\u003c/span\\u003e\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esearch-form\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eonChange\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eevent\\u003c/span\\u003e) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003esubmit\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eevent\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ecurrentTarget\\u003c/span\\u003e)\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003erole\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esearch\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\u003e \\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"20\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003einput\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"21\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003earia-label\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eSearch contacts\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"22\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eclassName\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003esearching\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e?\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eloading\\u003c/span\\u003e\\\\\\\" \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\\\\\\"\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"23\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003edefaultValue\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eq\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e||\\u003c/span\\u003e \\\\\\\"\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"24\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eq\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"25\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ename\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eq\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"26\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eplaceholder\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eSearch\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"27\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003etype\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esearch\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"28\\\\\\\"\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"29\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"30\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003earia-hidden\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"31\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ehidden\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e!\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003esearching\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"32\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esearch-spinner\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"33\\\\\\\"\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"34\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"35\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"36\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"37\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"38\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"39\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"40\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"41\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ehtml\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"42\\\\\\\"\\u003e );\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"43\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eBonus points, avoid fading out the main screen when searching:\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/root.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/root.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(--base03)\\\\\\\"\\u003e// existing imports and exports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\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)\\\\\\\"\\u003eApp\\u003c/span\\u003e() {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing code\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\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=\\\\\\\"8\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eclassName\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003enavigation\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003estate\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e===\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eloading\\u003c/span\\u003e\\\\\\\" \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e\\u0026#x26;\\u0026#x26;\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e!\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003esearching\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e?\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eloading\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\\\\\\"\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003edetail\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e \\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eOutlet\\u003c/span\\u003e /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"20\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"21\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"22\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"23\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ehtml\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"24\\\\\\\"\\u003e );\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"25\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eYou should now have a nice spinner on the left side of the search input.\\u003c/p\\u003e\\\\n\\u003cimg class=\\\\\\\"tutorial\\\\\\\" loading=\\\\\\\"lazy\\\\\\\" src=\\\\\\\"/docs-images/contacts/20.webp\\\\\\\" /\\u003e\\\\n\\u003ch2 id=\\\\\\\"managing-the-history-stack\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#managing-the-history-stack\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eManaging the History Stack\\u003c/h2\\u003e\\\\n\\u003cp\\u003eSince the form is submitted for every keystroke, typing the characters \\\\\\\"alex\\\\\\\" and then deleting them with backspace results in a huge history stack 😂. We definitely don't want this:\\u003c/p\\u003e\\\\n\\u003cimg class=\\\\\\\"tutorial\\\\\\\" loading=\\\\\\\"lazy\\\\\\\" src=\\\\\\\"/docs-images/contacts/21.webp\\\\\\\" /\\u003e\\\\n\\u003cp\\u003eWe can avoid this by \\u003cem\\u003ereplacing\\u003c/em\\u003e the current entry in the history stack with the next page instead of pushing into it.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eUse \\u003ccode\\u003ereplace\\u003c/code\\u003e in \\u003ccode\\u003esubmit\\u003c/code\\u003e\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/root.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/root.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(--base03)\\\\\\\"\\u003e// existing imports and exports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\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)\\\\\\\"\\u003eApp\\u003c/span\\u003e() {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing code\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\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=\\\\\\\"8\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esidebar\\u003c/span\\u003e\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eid\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esearch-form\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eonChange\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eevent\\u003c/span\\u003e) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eisFirstSearch\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eq\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e===\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base09)\\\\\\\"\\u003enull\\u003c/span\\u003e;\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003esubmit\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eevent\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ecurrentTarget\\u003c/span\\u003e, {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e replace: \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e!\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eisFirstSearch\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\u003e });\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"20\\\\\\\"\\u003e }\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"21\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003erole\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003esearch\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"22\\\\\\\"\\u003e \\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"23\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"24\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eForm\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"25\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"26\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"27\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"28\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ediv\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"29\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* existing elements */\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"30\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebody\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"31\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ehtml\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"32\\\\\\\"\\u003e );\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"33\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eAfter a quick check if this is the first search or not, we decide to replace it. Now the first search will add a new entry, but every keystroke after that will replace the current entry. Instead of clicking back seven times to remove the search, users only have to click back once.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"forms-without-navigation\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#forms-without-navigation\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003e\\u003ccode\\u003eForm\\u003c/code\\u003es Without Navigation\\u003c/h2\\u003e\\\\n\\u003cp\\u003eSo far all of our forms have changed the URL. While these user flows are common, it's equally common to want to submit a form \\u003cem\\u003ewithout\\u003c/em\\u003e causing a navigation.\\u003c/p\\u003e\\\\n\\u003cp\\u003eFor these cases, we have \\u003ca href=\\\\\\\"../hooks/use-fetcher\\\\\\\"\\u003e\\u003ccode\\u003euseFetcher\\u003c/code\\u003e\\u003c/a\\u003e. It allows us to communicate with \\u003ccode\\u003eaction\\u003c/code\\u003es and \\u003ccode\\u003eloader\\u003c/code\\u003es without causing a navigation.\\u003c/p\\u003e\\\\n\\u003cp\\u003eThe ★ button on the contact page makes sense for this. We aren't creating or deleting a new record, and we don't want to change pages. We simply want to change the data on the page we're looking at.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eChange the \\u003ccode\\u003e\\u0026#x3C;Favorite\\u003e\\u003c/code\\u003e form to a fetcher form\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/routes/contacts.$contactId.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/routes/contacts.$contactId.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(--base03)\\\\\\\"\\u003e// existing imports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eForm\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003euseFetcher\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003euseLoaderData\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\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=\\\\\\\"7\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing imports and exports\\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(--base03)\\\\\\\"\\u003e// existing code\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eFavorite\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eFunctionComponent\\u003c/span\\u003e\\u0026#x3C;{\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003ePick\\u003c/span\\u003e\\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eContactRecord\\u003c/span\\u003e, \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003efavorite\\u003c/span\\u003e\\\\\\\"\\u003e;\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e}\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e ({ \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e }) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efetcher\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseFetcher\\u003c/span\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efavorite\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efavorite\\u003c/span\\u003e;\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003efetcher.Form\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003emethod\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003epost\\u003c/span\\u003e\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebutton\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"20\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003earia-label\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"21\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efavorite\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"22\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e?\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eRemove from favorites\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"23\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eAdd to favorites\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"24\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"25\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ename\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003efavorite\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"26\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003evalue\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efavorite\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e?\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003efalse\\u003c/span\\u003e\\\\\\\" \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003etrue\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"27\\\\\\\"\\u003e \\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"28\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efavorite\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e?\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e★\\u003c/span\\u003e\\\\\\\" \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e☆\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"29\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebutton\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"30\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003efetcher.Form\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"31\\\\\\\"\\u003e );\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"32\\\\\\\"\\u003e};\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eThis form will no longer cause a navigation, but simply fetch to the \\u003ccode\\u003eaction\\u003c/code\\u003e. Speaking of which ... this won't work until we create the \\u003ccode\\u003eaction\\u003c/code\\u003e.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eCreate the \\u003ccode\\u003eaction\\u003c/code\\u003e\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/routes/contacts.$contactId.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/routes/contacts.$contactId.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)\\\\\\\"\\u003eimport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etype\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eActionFunctionArgs\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eLoaderFunctionArgs\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e} \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/node\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing imports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003egetContact\\u003c/span\\u003e, \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eupdateContact\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e../data\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing imports\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eaction\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003easync\\u003c/span\\u003e ({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003erequest\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e}\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eActionFunctionArgs\\u003c/span\\u003e) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003einvariant\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtactId\\u003c/span\\u003e, \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eMissing contactId param\\u003c/span\\u003e\\\\\\\");\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eformData\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eawait\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003erequest\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eformData\\u003c/span\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eupdateContact\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eparams\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtactId\\u003c/span\\u003e, {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e favorite: \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eformData\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eget\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003efavorite\\u003c/span\\u003e\\\\\\\") \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e===\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003etrue\\u003c/span\\u003e\\\\\\\",\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e });\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\u003e};\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"20\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"21\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// existing code\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eAlright, we're ready to click the star next to the user's name!\\u003c/p\\u003e\\\\n\\u003cimg class=\\\\\\\"tutorial\\\\\\\" loading=\\\\\\\"lazy\\\\\\\" src=\\\\\\\"/docs-images/contacts/22.webp\\\\\\\" /\\u003e\\\\n\\u003cp\\u003eCheck that out, both stars automatically update. Our new \\u003ccode\\u003e\\u0026#x3C;fetcher.Form method=\\\\\\\"post\\\\\\\"\\u003e\\u003c/code\\u003e works almost exactly like the \\u003ccode\\u003e\\u0026#x3C;Form\\u003e\\u003c/code\\u003e we've been using: it calls the action and then all data is revalidated automatically — even your errors will be caught the same way.\\u003c/p\\u003e\\\\n\\u003cp\\u003eThere is one key difference, though, it's not a navigation, so the URL doesn't change, and the history stack is unaffected.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"optimistic-ui\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#optimistic-ui\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eOptimistic UI\\u003c/h2\\u003e\\\\n\\u003cp\\u003eYou probably noticed the app felt kind of unresponsive when we clicked the favorite button from the last section. Once again, we added some network latency because you're going to have it in the real world.\\u003c/p\\u003e\\\\n\\u003cp\\u003eTo give the user some , we could put the star into a loading state with \\u003ca href=\\\\\\\"../hooks/use-fetcher#fetcherstate\\\\\\\"\\u003e\\u003ccode\\u003efetcher.state\\u003c/code\\u003e\\u003c/a\\u003e (a lot like \\u003ccode\\u003enavigation.state\\u003c/code\\u003e from before), but we can do something even better this time. We can use a strategy called \\\\\\\"Optimistic UI\\\\\\\".\\u003c/p\\u003e\\\\n\\u003cp\\u003eThe fetcher knows the \\u003ca href=\\\\\\\"https://developer.mozilla.org/en-US/docs/Web/API/FormData\\\\\\\"\\u003e\\u003ccode\\u003eFormData\\u003c/code\\u003e\\u003c/a\\u003e being submitted to the \\u003ccode\\u003eaction\\u003c/code\\u003e, so it's available to you on \\u003ccode\\u003efetcher.formData\\u003c/code\\u003e. We'll use that to immediately update the star's state, even though the network hasn't finished. If the update eventually fails, the UI will revert to the real data.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eRead the optimistic value from \\u003ccode\\u003efetcher.formData\\u003c/code\\u003e\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/routes/contacts.$contactId.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/routes/contacts.$contactId.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(--base03)\\\\\\\"\\u003e// existing code\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eFavorite\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eFunctionComponent\\u003c/span\\u003e\\u0026#x3C;{\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003ePick\\u003c/span\\u003e\\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eContactRecord\\u003c/span\\u003e, \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003efavorite\\u003c/span\\u003e\\\\\\\"\\u003e;\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e}\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e ({ \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e }) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efetcher\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003euseFetcher\\u003c/span\\u003e();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efavorite\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efetcher\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eformData\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e?\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efetcher\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eformData\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eget\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003efavorite\\u003c/span\\u003e\\\\\\\") \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e===\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003etrue\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econtact\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efavorite\\u003c/span\\u003e;\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003efetcher.Form\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003emethod\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003epost\\u003c/span\\u003e\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e \\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebutton\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003earia-label\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efavorite\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e?\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eRemove from favorites\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eAdd to favorites\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ename\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003efavorite\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"20\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003evalue\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efavorite\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e?\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003efalse\\u003c/span\\u003e\\\\\\\" \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003etrue\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"21\\\\\\\"\\u003e \\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"22\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e{\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003efavorite\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e?\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e★\\u003c/span\\u003e\\\\\\\" \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e☆\\u003c/span\\u003e\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0F)\\\\\\\"\\u003e}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"23\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebutton\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"24\\\\\\\"\\u003e \\u0026#x3C;/\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003efetcher.Form\\u003c/span\\u003e\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"25\\\\\\\"\\u003e );\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"26\\\\\\\"\\u003e};\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eNow the star \\u003cem\\u003eimmediately\\u003c/em\\u003e changes to the new state when you click it.\\u003c/p\\u003e\\\\n\\u003chr\\u003e\\\\n\\u003cp\\u003eThat's it! Thanks for giving Remix a try. We hope this tutorial gives you a solid start to build great user experiences. There's a lot more you can do, so make sure to check out all the APIs 😀\\u003c/p\\u003e\\\",\\\"docs/start/tutorial\\\",\\\"headings\\\",[960,965,968,971,974,977,980,983,986,989,992,995,998,1001,1004,1007,1010,1013,1016,1019,1022,1025,1028,1031,1034,1037,1040,1043],{\\\"_961\\\":962,\\\"_955\\\":963,\\\"_24\\\":964},\\\"headingLevel\\\",\\\"h2\\\",\\\"Setup\\\",\\\"setup\\\",{\\\"_961\\\":962,\\\"_955\\\":966,\\\"_24\\\":967},\\\"The Root Route\\\",\\\"the-root-route\\\",{\\\"_961\\\":962,\\\"_955\\\":969,\\\"_24\\\":970},\\\"Adding Stylesheets with \\u003ccode\\u003elinks\\u003c/code\\u003e\\\",\\\"adding-stylesheets-with-links\\\",{\\\"_961\\\":962,\\\"_955\\\":972,\\\"_24\\\":973},\\\"The Contact Route UI\\\",\\\"the-contact-route-ui\\\",{\\\"_961\\\":962,\\\"_955\\\":975,\\\"_24\\\":976},\\\"Nested Routes and Outlets\\\",\\\"nested-routes-and-outlets\\\",{\\\"_961\\\":962,\\\"_955\\\":978,\\\"_24\\\":979},\\\"Client Side Routing\\\",\\\"client-side-routing\\\",{\\\"_961\\\":962,\\\"_955\\\":981,\\\"_24\\\":982},\\\"Loading Data\\\",\\\"loading-data\\\",{\\\"_961\\\":962,\\\"_955\\\":984,\\\"_24\\\":985},\\\"Type Inference\\\",\\\"type-inference\\\",{\\\"_961\\\":962,\\\"_955\\\":987,\\\"_24\\\":988},\\\"URL Params in Loaders\\\",\\\"url-params-in-loaders\\\",{\\\"_961\\\":962,\\\"_955\\\":990,\\\"_24\\\":991},\\\"Validating Params and Throwing Responses\\\",\\\"validating-params-and-throwing-responses\\\",{\\\"_961\\\":962,\\\"_955\\\":993,\\\"_24\\\":994},\\\"Data Mutations\\\",\\\"data-mutations\\\",{\\\"_961\\\":962,\\\"_955\\\":996,\\\"_24\\\":997},\\\"Creating Contacts\\\",\\\"creating-contacts\\\",{\\\"_961\\\":962,\\\"_955\\\":999,\\\"_24\\\":1000},\\\"Updating Data\\\",\\\"updating-data\\\",{\\\"_961\\\":962,\\\"_955\\\":1002,\\\"_24\\\":1003},\\\"Updating Contacts with \\u003ccode\\u003eFormData\\u003c/code\\u003e\\\",\\\"updating-contacts-with-formdata\\\",{\\\"_961\\\":962,\\\"_955\\\":1005,\\\"_24\\\":1006},\\\"Mutation Discussion\\\",\\\"mutation-discussion\\\",{\\\"_961\\\":962,\\\"_955\\\":1008,\\\"_24\\\":1009},\\\"Redirecting new records to the edit page\\\",\\\"redirecting-new-records-to-the-edit-page\\\",{\\\"_961\\\":962,\\\"_955\\\":1011,\\\"_24\\\":1012},\\\"Active Link Styling\\\",\\\"active-link-styling\\\",{\\\"_961\\\":962,\\\"_955\\\":1014,\\\"_24\\\":1015},\\\"Global Pending UI\\\",\\\"global-pending-ui\\\",{\\\"_961\\\":962,\\\"_955\\\":1017,\\\"_24\\\":1018},\\\"Deleting Records\\\",\\\"deleting-records\\\",{\\\"_961\\\":962,\\\"_955\\\":1020,\\\"_24\\\":1021},\\\"Index Routes\\\",\\\"index-routes\\\",{\\\"_961\\\":962,\\\"_955\\\":1023,\\\"_24\\\":1024},\\\"Cancel Button\\\",\\\"cancel-button\\\",{\\\"_961\\\":962,\\\"_955\\\":1026,\\\"_24\\\":1027},\\\"\\u003ccode\\u003eURLSearchParams\\u003c/code\\u003e and \\u003ccode\\u003eGET\\u003c/code\\u003e Submissions\\\",\\\"urlsearchparams-and-get-submissions\\\",{\\\"_961\\\":962,\\\"_955\\\":1029,\\\"_24\\\":1030},\\\"Synchronizing URLs to Form State\\\",\\\"synchronizing-urls-to-form-state\\\",{\\\"_961\\\":962,\\\"_955\\\":1032,\\\"_24\\\":1033},\\\"Submitting \\u003ccode\\u003eForm\\u003c/code\\u003e's \\u003ccode\\u003eonChange\\u003c/code\\u003e\\\",\\\"submitting-forms-onchange\\\",{\\\"_961\\\":962,\\\"_955\\\":1035,\\\"_24\\\":1036},\\\"Adding Search Spinner\\\",\\\"adding-search-spinner\\\",{\\\"_961\\\":962,\\\"_955\\\":1038,\\\"_24\\\":1039},\\\"Managing the History Stack\\\",\\\"managing-the-history-stack\\\",{\\\"_961\\\":962,\\\"_955\\\":1041,\\\"_24\\\":1042},\\\"\\u003ccode\\u003eForm\\u003c/code\\u003es Without Navigation\\\",\\\"forms-without-navigation\\\",{\\\"_961\\\":962,\\\"_955\\\":1044,\\\"_24\\\":1045},\\\"Optimistic UI\\\",\\\"optimistic-ui\\\",[],\\\"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/start/tutorial",
|
||
"metadata": {
|
||
"description": "",
|
||
"headings": [
|
||
"Remix Tutorial",
|
||
"Setup",
|
||
"The Root Route",
|
||
"Adding Stylesheets with links",
|
||
"The Contact Route UI",
|
||
"Nested Routes and Outlets",
|
||
"Client Side Routing",
|
||
"Loading Data",
|
||
"Type Inference",
|
||
"URL Params in Loaders",
|
||
"Validating Params and Throwing Responses",
|
||
"Data Mutations",
|
||
"Creating Contacts",
|
||
"Updating Data",
|
||
"Updating Contacts with FormData",
|
||
"Mutation Discussion",
|
||
"Redirecting new records to the edit page",
|
||
"Active Link Styling",
|
||
"Global Pending UI",
|
||
"Deleting Records",
|
||
"Index Routes",
|
||
"Cancel Button",
|
||
"URLSearchParams and GET Submissions",
|
||
"Synchronizing URLs to Form State",
|
||
"Submitting Form's onChange",
|
||
"Adding Search Spinner",
|
||
"Managing the History Stack",
|
||
"Forms Without Navigation",
|
||
"Optimistic UI"
|
||
],
|
||
"images": [
|
||
"/docs-images/contacts/01.webp",
|
||
"/docs-images/contacts/03.webp",
|
||
"/docs-images/contacts/04.webp",
|
||
"/docs-images/contacts/05.webp",
|
||
"/docs-images/contacts/06.webp",
|
||
"/docs-images/contacts/07.webp",
|
||
"/docs-images/contacts/08.webp",
|
||
"/docs-images/contacts/10.webp",
|
||
"/docs-images/contacts/09.webp",
|
||
"/docs-images/contacts/11.webp",
|
||
"/docs-images/contacts/12.webp",
|
||
"/docs-images/contacts/13.webp",
|
||
"/docs-images/contacts/14.webp",
|
||
"/docs-images/contacts/15.webp",
|
||
"/docs-images/contacts/16.webp",
|
||
"/docs-images/contacts/17.webp",
|
||
"/docs-images/contacts/18.webp",
|
||
"/docs-images/contacts/19.webp",
|
||
"/docs-images/contacts/20.webp",
|
||
"/docs-images/contacts/21.webp",
|
||
"/docs-images/contacts/22.webp",
|
||
"/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/start/tutorial/#setup",
|
||
"/docs/start/tutorial/#the-root-route",
|
||
"/docs/start/tutorial/#adding-stylesheets-with-links",
|
||
"/docs/start/tutorial/#the-contact-route-ui",
|
||
"/docs/start/tutorial/#nested-routes-and-outlets",
|
||
"/docs/start/tutorial/#client-side-routing",
|
||
"/docs/start/tutorial/#loading-data",
|
||
"/docs/start/tutorial/#type-inference",
|
||
"/docs/start/tutorial/#url-params-in-loaders",
|
||
"/docs/start/tutorial/#validating-params-and-throwing-responses",
|
||
"/docs/start/tutorial/#data-mutations",
|
||
"/docs/start/tutorial/#creating-contacts",
|
||
"/docs/start/tutorial/#updating-data",
|
||
"/docs/start/tutorial/#updating-contacts-with-formdata",
|
||
"/docs/start/tutorial/#mutation-discussion",
|
||
"/docs/start/tutorial/#redirecting-new-records-to-the-edit-page",
|
||
"/docs/start/tutorial/#active-link-styling",
|
||
"/docs/start/tutorial/#global-pending-ui",
|
||
"/docs/start/tutorial/#deleting-records",
|
||
"/docs/start/tutorial/#index-routes",
|
||
"/docs/start/tutorial/#cancel-button",
|
||
"/docs/start/tutorial/#urlsearchparams-and-get-submissions",
|
||
"/docs/start/tutorial/#synchronizing-urls-to-form-state",
|
||
"/docs/start/tutorial/#submitting-forms-onchange",
|
||
"/docs/start/tutorial/#adding-search-spinner",
|
||
"/docs/start/tutorial/#managing-the-history-stack",
|
||
"/docs/start/tutorial/#forms-without-navigation",
|
||
"/docs/start/tutorial/#optimistic-ui",
|
||
"https://remix.run/blog/incremental-path-to-react-19",
|
||
"https://reactrouter.com/tutorials/address-book",
|
||
"./quickstart",
|
||
"http://localhost:5173",
|
||
"../route/links",
|
||
"https://blog.jim-nielsen.com",
|
||
"../file-conventions/routes",
|
||
"../components/outlet",
|
||
"../components/link",
|
||
"../route/loader",
|
||
"../hooks/use-loader-data",
|
||
"../route/loader#params",
|
||
"https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams",
|
||
"../route/action",
|
||
"../components/form",
|
||
"https://developer.mozilla.org/en-US/docs/Web/API/fetch",
|
||
"https://developer.mozilla.org/en-US/docs/Web/API/FormData",
|
||
"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries",
|
||
"https://developer.mozilla.org/en-US/docs/Web/API/Request",
|
||
"https://developer.mozilla.org/en-US/docs/Web/API/Request/formData",
|
||
"../utils/redirect",
|
||
"../route/loader#returning-response-instances",
|
||
"https://developer.mozilla.org/en-US/docs/Web/API/Response",
|
||
"../components/nav-link",
|
||
"../hooks/use-navigation",
|
||
"../hooks/use-navigate",
|
||
"../hooks/use-submit",
|
||
"../hooks/use-fetcher",
|
||
"../hooks/use-fetcher#fetcherstate",
|
||
"https://remix.run",
|
||
"https://opensource.org/licenses/MIT",
|
||
"https://github.com/remix-run/remix-v2-website/edit/main/data/docs/start/tutorial.md"
|
||
]
|
||
},
|
||
"hash": "693c870e529353ff760b1c63b06c7de530bb486840986e321f901f839e44c258",
|
||
"timestamp": "2026-02-23T11:36:17.833638728+01:00"
|
||
} |