Skip to content

Commit

Permalink
add: csp, nonce & defer
Browse files Browse the repository at this point in the history
  • Loading branch information
jvanst committed Feb 22, 2023
1 parent 36a0800 commit e6dcfd0
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 30 deletions.
3 changes: 3 additions & 0 deletions app/components/NonceContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import React from 'react';

export const NonceContext = React.createContext<string | undefined>(undefined);
17 changes: 15 additions & 2 deletions app/entry.server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ import { RemixServer } from "@remix-run/react";
import isbot from "isbot";
import { renderToPipeableStream } from "react-dom/server";

import { NonceContext } from "./components/NonceContext";

// In real applications you would generate a new nonce for each request.
const NONCE = "sample-nonce";

const ABORT_DELAY = 5000;

export default function handleRequest(
Expand All @@ -13,6 +18,8 @@ export default function handleRequest(
responseHeaders: Headers,
remixContext: EntryContext
) {
responseHeaders.set('Content-Security-Policy', `script-src 'self' 'nonce-${NONCE}';`)

return isbot(request.headers.get("user-agent"))
? handleBotRequest(
request,
Expand All @@ -38,8 +45,11 @@ function handleBotRequest(
let didError = false;

const { pipe, abort } = renderToPipeableStream(
<RemixServer context={remixContext} url={request.url} />,
<NonceContext.Provider value={NONCE}>
<RemixServer context={remixContext} url={request.url} />
</NonceContext.Provider>,
{
nonce: NONCE,
onAllReady() {
const body = new PassThrough();

Expand Down Expand Up @@ -79,8 +89,11 @@ function handleBrowserRequest(
let didError = false;

const { pipe, abort } = renderToPipeableStream(
<RemixServer context={remixContext} url={request.url} />,
<NonceContext.Provider value={NONCE}>
<RemixServer context={remixContext} url={request.url} />
</NonceContext.Provider>,
{
nonce: NONCE,
onShellReady() {
const body = new PassThrough();

Expand Down
10 changes: 7 additions & 3 deletions app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
Scripts,
ScrollRestoration,
} from "@remix-run/react";
import { useContext } from "react";
import { NonceContext } from "./components/NonceContext";

export const meta: MetaFunction = () => ({
charset: "utf-8",
Expand All @@ -15,6 +17,8 @@ export const meta: MetaFunction = () => ({
});

export default function App() {
const nonce = useContext(NonceContext);

return (
<html lang="en">
<head>
Expand All @@ -23,9 +27,9 @@ export default function App() {
</head>
<body>
<Outlet />
<ScrollRestoration />
<Scripts />
<LiveReload />
<ScrollRestoration nonce={nonce} />
<Scripts nonce={nonce} />
<LiveReload nonce={nonce} />
</body>
</html>
);
Expand Down
31 changes: 31 additions & 0 deletions app/routes/defer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { defer } from "@remix-run/node";
import { Await, useLoaderData } from "@remix-run/react";
import { Suspense } from "react";

export const loader = () => {
return defer({
critical: "data",
slowPromise: new Promise((resolve) => setTimeout(() => resolve('Slow promise content'), 1000)),
});
};

export default function Defer() {
const data = useLoaderData<typeof loader>();

return (
<div>
<Suspense fallback={<p>Loading deffered content</p>}>
<Await
resolve={data.slowPromise}
errorElement={<p>Error loading deffered content!</p>}
>
{(content) => (
<p>
{content}
</p>
)}
</Await>
</Suspense>
</div>
);
}
28 changes: 3 additions & 25 deletions app/routes/index.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,10 @@
import { Link } from "@remix-run/react";

export default function Index() {
return (
<div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.4" }}>
<h1>Welcome to Remix</h1>
<ul>
<li>
<a
target="_blank"
href="https://remix.run/tutorials/blog"
rel="noreferrer"
>
15m Quickstart Blog Tutorial
</a>
</li>
<li>
<a
target="_blank"
href="https://remix.run/tutorials/jokes"
rel="noreferrer"
>
Deep Dive Jokes App Tutorial
</a>
</li>
<li>
<a target="_blank" href="https://remix.run/docs" rel="noreferrer">
Remix Docs
</a>
</li>
</ul>
<Link to="/defer">Go to defer</Link>
</div>
);
}

0 comments on commit e6dcfd0

Please sign in to comment.