You’ve most likely heard quite a lot of hype round one of many latest youngsters on the framework block, Remix. It might be shocking that it received its begin again in 2019, but it surely was initially solely out there as a subscription-based premium framework. In 2021, the founders raised seed funding and open sourced the framework to let customers begin utilizing Remix without cost. The floodgates opened and everybody appears to be speaking about it, good or unhealthy. Let’s dive in and have a look at among the fundamentals of Remix.
Remix is a server “edge” first JavaScript framework. It makes use of React, not less than for now, for the entrance finish and prioritizes server-side rendering the appliance on the sting. Platforms can take the server-side code and run it as serverless or edge features making it cheaper than a conventional server and placing it nearer to your customers. The Remix founders wish to name it a “middle stack” framework as a result of it adapts the requests and responses made between the server and the shopper for the platform it’s being run on.
Deploying Remix
As a result of Remix requires a server, let’s speak about how one can deploy it. Remix doesn’t present the server itself — you deliver the server — permitting it to be run in any Node.js or Deno surroundings, together with Netlify Edge and DigitalOcean’s App Platform. Remix itself is a compiler, a program that interprets the requests for the platform it’s working on. This course of makes use of esbuild to create handlers for the requests to the server. The HTTP handlers it makes use of are constructed on the Net Fetch API and are ran on the server by adapting them for the platform they are going to be deployed to.
Remix stacks
Remix stacks are initiatives which have some widespread instruments that come preconfigured for you. There are three official stacks which might be maintained by the Remix group and they’re all named after musical genres. There’s additionally quite a few group Remix stacks together with the Okay-Pop Stack created by the Templates Group at Netlify. This stack is a powerhouse and features a Supabase database and authentication, Tailwind for styling, Cypress end-to-end testing, Prettier code formatting, ESLint linting, and TypeScript static typing. Try Tara Manicsic’s publish on deploying the Okay-Pop Stack.
Caching routes
Although Remix requires a server, it may nonetheless reap the benefits of the Jamstack advantages by caching routes. A static website or static website era (SSG) is when your whole content material is rendered at construct time and stays static till one other rebuild. The content material is pre-generated and may be placed on a CDN. This offers many advantages and speedy website hundreds for the tip person. Nonetheless, Remix doesn’t do typical SSG like different well-liked React frameworks, together with Subsequent.js and Gatsby. To get the among the advantages of SSG, you need to use the native Cache-Management HTTP header in a Remix headers perform to cache a selected route or instantly within the root.tsx
file.
[[headers]]
for = "/construct/*"
[headers.values]
"Cache-Management" = "public, max-age=31536000, s-maxage=31536000"
Then add in your headers perform the place you need it. This caches for one hour:
export perform headers() {
return {
"Cache-Management": "public, s-maxage=360",
};
};
Remixing routing
A variety of frameworks have leaned into routing based mostly on file methods. It is a approach the place a chosen folder is used to outline routes in your utility. They sometimes have particular syntax for declaring dynamic routes and endpoints. The most important distinction presently between Remix and different well-liked frameworks is the flexibility to make use of nested routing.
Each Remix app begins with the root.tsx
file. That is the place the complete base of the app is rendered. You’ll discover among the widespread HTML format right here just like the <html>
tag, the <head>
tag, after which the <physique>
tag with the parts wanted to render the app. The one factor to level out right here is the <Scripts>
part is what permits JavaScript on the positioning; some issues will work with out it, however not every thing. The root.tsx
file acts as a guardian format for every thing inside the routes
listing, every thing in routes is rendered the place the <Outlet/>
part is in root.tsx
. That is the bottom of nested routing in Remix.
Nested routing
Not solely was Remix based by among the group from React Router, it additionally makes use of React Router. The truth is, they’re bringing among the good issues about Remix again to React Router. A fancy drawback that the maintainers of Subsequent.js and SvelteKit try to unravel proper now could be nested routing.
Nested routing is in contrast to conventional routing. The place a brand new route would take a person to a brand new web page, every nested route is a separate part of the identical web page. It permits for separation of issues by retaining enterprise logic related to solely the recordsdata that want it. Remix is ready to deal with errors localized to solely the part of the web page the nested route is at. The opposite routes on the web page are nonetheless usable and the route that broke can present related context to the error with out the complete web page crashing.
Remix does this when a root file in app/routes
is known as the identical as a listing of recordsdata that may load inside the bottom file. The foundation file turns into a format for the recordsdata within the listing by utilizing an <Outlet />
part to inform Remix the place to load the opposite routes.
Outlet part
The <Outlet />
Element is a sign to Remix for the place it ought to render content material for nested routes. It’s put within the file on the root of the app/routes
listing with the identical title because the nested routes. The next code goes in a app/routes/about.tsx
file and consists of the outlet for the recordsdata inside app/routes/about
folder:
import { Outlet } from "@remix-run/react";
export default perform About() {
return (
<>
<part>
I'm the guardian format. I will probably be on any web page inside my named listing.
</part>
{ /* All of my youngsters, the recordsdata within the named listing, will go right here. */ }
<Outlet />
</>
)
}
Folder construction
Any file within the app/routes/
listing turns into a route on the URL of its title. A listing may also be added with an index.tsx
file.
app/
├── routes/
│ │
│ └── weblog
| | ├── index.tsx ## The /weblog route
│ └── about.tsx ## The /about route
│ ├── index.tsx ## The / or residence route
└── root.tsx
If a route has the identical title as a listing, the named file turns into a format file for the recordsdata contained in the listing and the format file wants an Outlet part to put the nested route in.
app/
├── routes/
│ │
│ └── about
│ │ ├── index.tsx
│ ├── about.tsx ## it is a format for /about/index.tsx
│ ├── index.tsx
└── root.tsx
Layouts may also be created by prefixing them with a double underscore (__
).
app/
├── routes/
│ │
│ └── about
│ │ ├── index.tsx
│ ├── index.tsx
│ ├── about.tsx
│ ├── __blog.tsx ## that is additionally a format
└── root.tsx
https://your-url.com/about
will nonetheless render the app/routes/about.tsx
file, however may also render no matter is in app/routes/about/index.tsx
the place the Outlet part is within the markup of app/routes/about.tsx
.
Dynamic Routes
A dynamic route is a route that modifications based mostly on info within the url. That could be a reputation of a weblog publish or a buyer id, however it doesn’t matter what it’s the $
syntax added to the entrance of the route alerts to Remix that it’s dynamic. The title doesn’t matter aside from the $
prefix.
app/
├── routes/
│ │
│ └── about
│ │ ├── $id.tsx
│ │ ├── index.tsx
│ ├── about.tsx ## it is a format for /about/index.tsx
│ ├── index.tsx
└── root.tsx
Fetch that information!
Since Remix renders all of its information on the server, you don’t see quite a lot of the issues which have turn out to be the usual of a React app, like useState()
and useEffect()
hooks, in Remix. There’s much less want for client-side state because it has already been evaluated on the server.
It additionally doesn’t matter what kind of server you utilize for fetching information. Since Remix sits between the request and response and interprets it appropriately, you need to use the usual Net Fetch API. Remix does this in a loader
perform that solely runs on the server and makes use of the useLoaderData()
hook to render the information within the part. Right here’s an instance utilizing the Cat as a Service API to render a random cat picture.
import { Outlet, useLoaderData } from '@remix-run/react'
export async perform loader() {
const response = await fetch('<https://cataas.com/cat?json=true>')
const information = await response.json()
return {
information
}
}
export default perform AboutLayout() {
const cat = useLoaderData<typeof loader>()
return (
<>
<img
src={`https://cataas.com/cat/${cat}`}
alt="A random cat."
/>
<Outlet />
</>
)
}
Route parameters
In dynamic routes, routes prefixed with $
want to have the ability to entry the URL parameter to deal with that information that must be rendered. The loader
perform has entry to those via a params
argument.
import { useLoaderData } from '@remix-run/react'
import kind { LoaderArgs } from '@remix-run/node'
export async perform loader({ params }: LoaderArgs) {
return {
params
}
}
export default perform AboutLayout() {
const { params } = useLoaderData<typeof loader>()
return <p>The url parameter is {params.tag}.</p>
}
Different Remix features
Remix has a number of different helper features that add further performance to regular HTML components and attributes within the route module API. Every route can outline its personal of a majority of these features.
Motion perform
An motion
perform lets you add further performance to a type motion utilizing the usual internet FormData API.
export async perform motion({ request }) {
const physique = await request.formData();
const todo = await fakeCreateTodo({
title: physique.get("title"),
});
return redirect(`/todos/${todo.id}`);
}
Any HTTP customary headers can go in a headers
perform. As a result of every route can have a header, to keep away from conflicts with nested routes, the deepest route — or the URL with probably the most ahead slashes (/
) — wins. You too can get the headers handed via, actionHeaders
, loaderHeaders
, or parentHeaders
export perform headers({
actionHeaders,
loaderHeaders,
parentHeaders,
}) {
return {
"Cache-Management": loaderHeaders.get("Cache-Management"),
};
}
Meta perform
This perform will set the meta tags for the HTML doc. One is about within the root.tsx
file by default, however they are often up to date for every route.
export perform meta() {
return {
title: "Your web page title",
description: "A brand new description for every route.",
};
};
Hyperlinks perform
HTML hyperlink
components stay within the <head>
tag of an HTML doc and so they import CSS, amongst different issues. The hyperlinks
perform, to not be confused with the <Hyperlink />
part, lets you solely import issues within the routes that want them. So, for instance, CSS recordsdata may be scoped and solely imported on the routes that want these particular recordsdata. The hyperlink
components are returned from a hyperlinks()
perform as an array of objects and may both be a HtmlLinkDescriptor
from the hyperlink
API or a PageLinkDescriptor
that may prefetch the information for a web page.
export perform hyperlinks() {
return [
// add a favicon
{
rel: "icon",
href: "/favicon.png",
type: "image/png",
},
// add an external stylesheet
{
rel: "stylesheet",
href: "<https://example.com/some/styles.css>",
crossOrigin: "true",
},
// add a local stylesheet,
{ rel: "stylesheet", href: stylesHref },
// prefetch a page's data
{ page: "/about/community" }
]
}
Linking between routes
Remix offers a part to go between the completely different routes in your app known as <Hyperlink/>
. To get client-side routing, use the <Hyperlink to="">Title</Hyperlink>
part as a substitute of <a href="">Title</a>
. The <Hyperlink />
part additionally takes a prop of prefetch
with accepts none
by default, intent
to prefetch the information if Remix detects the person hovers or focuses the hyperlink, or render
which is able to fetch the route’s information as quickly because the hyperlink is rendered.
import { Hyperlink } from "@remix-run/react";
export default perform Nav() {
return (
<nav>
<Hyperlink to="https://css-tricks.com/">Residence</Hyperlink>{" "}
<Hyperlink to="/about">About</Hyperlink>{" "}
<Hyperlink to="/about/group" prefetch="intent">Group</Hyperlink>
</nav>
);
}
Subsequent steps
Now the fundamentals of Remix and also you’re able to get began really constructing purposes, proper? Remix offers a Jokes app and a Weblog tutorial to get you began implementing this primary information. You too can begin from scratch and create a model new Remix app. Or in case you are able to dive in, give the Okay-Pop Stack a strive. I’ve actually loved my time with Remix and love the give attention to internet requirements and bringing it again to the fundamentals. Now it’s your flip to begin creating!