Ryan Florence & Michael Jackson
Use the platform, Luke
JS = améliorer l'UX
.
Un dossier app/routes
Un fichier -> un « route module » (basé sur React Router)
export default function Index() { const data = useRouteData(); return ( <div className="home-page"> <Banner /> <FeedLayout> <Outlet /> </FeedLayout> <TagList tags={data.tags} /> </div> );};
export const loader = async function ({ params }) { const article = await getArticle(params.articleSlug); if (article === null) { return new Response(null, { status: 404 }); } return json({ article });};
export const links = () => [ { rel: "stylesheet", href: stylesUrl }, { rel: "preload", as: "fetch", "href": "urlFetchProbable" }]; export const headers = () => ({ "X-Secret-Location": "Mobile Meth Lab", "Cache-Control": "max-age=300, s-maxage=3600"}); export const meta = () => ({ title: "Something cool", description: "This becomes the nice preview on search results."});
root.js routes ┣━━ index.js ┣━━ invoices.js ┣━━ invoices.new.js ┃ ┗━━ invoices ┣━━ index.js ┗━━ $slug.js
root.js // Route commune à toutes les pages routes ┣━━ index.js // utilisé pour '/' ┣━━ invoices.js // utilisé pour '/invoices' ┣━━ invoices.new.js // utilisé pour '/invoices/new' ┃ ┗━━ invoices ┣━━ index.js // utilisé pour '/invoices' ┗━━ $slug.js // utilisé pour '/invoices/1234'
export const action = async function action({ request }) { const requestBody = new URLSearchParams(await request.text()); const login = requestBody.get("login"); const password = requestBody.get("password"); // perform login... return new Response("", { status: 302, headers: { Location: "/feed", "Set-Cookie": await commitSession(...), } })};
function MyRemixForm() { return ( <Form action="/login" method="post"> <input type="text" /> <input type="password" /> <button type="submit">Login</button> </Form> )}
function MyRemixForm() { const pendingForm = useTransition().submission return ( <Form action="/login" method="post"> <input type="text" /> <input type="password" /> <button type="submit" disabled={pendingForm !== undefined}>Login</button> </Form> )}
const express = require("express");const { createRequestHandler } = require("@remix-run/express"); let app = express(); app.all( "*", createRequestHandler({ build: require("./build") })); app.listen(port, () => { console.log(`Express server started !`); });
const express = require("express");const { createRequestHandler } = require("@remix-run/express"); let app = express(); app.use(compression()) app.all( "*", createRequestHandler({ build: require("./build") })); app.listen(port, () => { console.log(`Express server started !`); });
const { createRequestHandler } = require("@remix-run/architect"); exports.handler = createRequestHandler({ build: require("./build"),});
export default function handleRequest(request, responseStatusCode, responseHeaders, remixContext) { const markup = ReactDOMServer.renderToString( <RemixServer context={remixContext} url={request.url} /> ); return new Response("<!DOCTYPE html>" + markup, { status: responseStatusCode, headers: { ...Object.fromEntries(responseHeaders), "Content-Type": "text/html" } });}
ReactDOM.hydrate( <RemixBrowser />, document);
// root.jsexport default function App() { return ( <html lang="en"> <head> <meta charSet="utf-8"/> <Meta/> <Links/> </head> <body> <Outlet/> <Scripts/> </body> </html> );}
// root.jsexport default function App() { return ( <html lang="en"> <head> <meta charSet="utf-8"/> <Meta/> <Links/> </head> <body> <Outlet/> <Scripts/> </body> </html> );}
static sites aren't the target of remix, and never will be, we think ssg is a weird phase of the web that will die soon.
— Ryan Florence
export function headers() { return { "Cache-Control": "public, max-age=604800, must-revalidate" };}