React Router is a multi-strategy router for React built on top of Vite. Gadget supports React Router in both framework and declarative modes for building app frontends.
Getting started with React Router v7
Picking a Mode
React Router can be run in framework or declarative mode. The mode you choose depends on which "top-level" router API you're using and whether you are comfortable with Remix-style frontend development.
Gadget's web templates offer both framework and declarative modes. Currently, the Shopify template only provides the Remix and React Router declarative mode.
Declarative
Declarative mode is also known as "client-side routing" or "Single Page Application (SPA) routing". Declarative mode enables basic routing features like matching URLs to components, navigating around the app, and providing active states with APIs like <Link>, useNavigate, and useLocation. This is the closest comparison to the React Router v6 API.
React
1import{BrowserRouter}from"react-router";
2
3ReactDOM.createRoot(root).render(
4<BrowserRouter>
5<App/>
6</BrowserRouter>
7);
1import{BrowserRouter}from"react-router";
2
3ReactDOM.createRoot(root).render(
4<BrowserRouter>
5<App/>
6</BrowserRouter>
7);
Framework
Framework mode is very similar to the Remix framework, which supports features like server-side rendering (SSR), file-based routing and more.
However, the React Router framework mode introduces a new "typesafe Route Module API" feature that generates route-specific types for power type inference for URL parameters, loader data, and more.
All Gadget templates in the framework mode are configured with the file-based routing using the @react-router/fs-routes package to provide a greater development experiment and smoother transition between Remix and React Router.
For more information about the differences between both modes, check out the guide from React Router.
Cold boot times for SSR
Gadget frontends are serverless and resources used are scaled to zero when not in use. This means that a frontend not in use needs to be
started fresh, referred to as a cold boot. This cold boot time may negatively impact web vitals like LCP.
Contact us if you are building in SSR model and need to minimize cold boot times.
Framework mode
Framework mode allows you to render your frontend on the server. Framework mode has multiple benefits:
improved performance by reducing the time it takes to load the page
better search engine optimization (SEO) because search engines can index the page content returned from the server
data fetching with loader functions to reduce client-side requests
form submissions with action functions, allowing for full-stack actions without client-side JavaScript
code splitting and reduced bundle size
Some Gadget-provided tools will not be rendered server-side, including:
You could opt out of SSR in framework mode by setting ssr: false in the react-router.config.ts file. However, in this section, we only focus on the SSR.
Auto-generated route module types
React Router generates route-specific types to power type inference for URL params, loader data, and more. Note that this is a TypeScript-only feature, and we have set it up for you.
To import the auto-generated types, you could write the import path like this:
File path
Import statement
web/routes/_index.tsx
import type { Route } from "./+types/_index";
web/routes/_user.todos.tsx
import type { Route } from "./+types/_user.todos";
web/routes/_public.blogs.$id.tsx
import type { Route } from "./+types/_public.blogs.$id";
Note that this conversation is only valid for the file-based routing we have set up for you.
To learn more about how type safety works in React Router, check out the guides from React Router.
Reading data with loader functions
You could use the loader function from Remix to fetch the data on the server-side.
Your Gadget app's context object is available in the loader function and is the same as the context you get when you create an action in Gadget. This allows you to interact with your Gadget backend and pass data to your frontend.
For example, you might have a loader function that fetches the model data like this:
Declarative mode enables basic routing features like matching URLs to components, navigating around the app, and providing active states with APIs like <Link>, useNavigate, and useLocation. It is useful if you want to use React Router as simply as possible or are coming from v6 and are happy with the <BrowserRouter>.