Skip to content

Commit

Permalink
Caching for web
Browse files Browse the repository at this point in the history
  • Loading branch information
oscartbeaumont committed Sep 14, 2024
1 parent 97256f4 commit f822d32
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 68 deletions.
101 changes: 46 additions & 55 deletions apps/web/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,19 @@ import "./src/env";
const nitroPreset = process.env.NITRO_PRESET ?? "node-server";
const isCFPages = nitroPreset === "cloudflare_pages";

// TODO: Maybe generate from Solid Router
// These skip the Worker so they can be served by CF's edge.
// (our Worker has smart placement for the API so it's not edge)
const staticRoutes = [
"/",
"/tos",
"/account",
"/invite",
"/login",
"/enroll",
"/o/*",
];

export default defineConfig({
ssr: false,
routeDir: "app",
Expand Down Expand Up @@ -81,65 +94,34 @@ export default defineConfig({
filename: "stats-nitro.html",
},
// We define these rules for production in `_headers`
routeRules: isCFPages
? {}
: {
"/**": {
// @ts-expect-error: This is in our patch
priority: 5,
headers: {
"Cache-Control": "public,max-age=0,must-revalidate",
"X-Frame-Options": "DENY",
"X-Content-Type-Options": "nosniff",
"Referrer-Policy": "strict-origin-when-cross-origin",
},
},
// TODO: Automatically generate from the Solid Router definition???
"/": {
headers: {
// Don't cache on client but cache in Cloudflare for 1hr and keep serving if the origin is offline for another hour.
// `no-transform` disables the Cloudflare Beacon which causes the Etag to get removed.
"Cache-Control":
"public, max-age=0, s-maxage=3600, stale-if-error=3600, no-transform",
},
},
"/tos": {
headers: {
"Cache-Control":
"public, max-age=0, s-maxage=3600, stale-if-error=3600, no-transform",
},
},
"/account": {
headers: {
"Cache-Control":
"public, max-age=0, s-maxage=3600, stale-if-error=3600, no-transform",
},
},
"/invite": {
headers: {
"Cache-Control":
"public, max-age=0, s-maxage=3600, stale-if-error=3600, no-transform",
},
},
"/login": {
headers: {
"Cache-Control":
"public, max-age=0, s-maxage=3600, stale-if-error=3600, no-transform",
},
},
"/enroll": {
headers: {
"Cache-Control":
"public, max-age=0, s-maxage=3600, stale-if-error=3600, no-transform",
},
},
"/o/*": {
routeRules: {
"/**": {
headers: {
"X-Frame-Options": "DENY",
"X-Content-Type-Options": "nosniff",
"Referrer-Policy": "strict-origin-when-cross-origin",
"Strict-Transport-Security":
"max-age=31536000; includeSubDomains; preload",
},
},
"/favicon.ico": {
headers: {
"Cache-Control":
"public, max-age=1440, s-maxage=1440, stale-if-error=1440, no-transform",
},
},
...Object.fromEntries(
staticRoutes.map((route) => [
route,
{
headers: {
"Cache-Control":
"public, max-age=0, s-maxage=3600, stale-if-error=3600, no-transform",
},
},
},
]),
),
},
...(isCFPages && {
// TODO: We could probs PR this to the Vercel Edge preset in Nitro.
// This is to ensure Stripe pulls in the Cloudflare Workers version not the Node version.
Expand Down Expand Up @@ -172,9 +154,18 @@ process.on("exit", () => {
JSON.stringify({
version: 1,
include: ["/*"],
exclude: ["/_build/*", "/assets/*", "/favicon.ico", "/tos"],
exclude: [
// HTML/favicon.ico routes
...staticRoutes,
// Handled by `_redirects`
"/EnrollmentServer/*",
// Static files
"/_build/*",
"/assets/*",
],
}),
);

console.log("Patched `_routes.json`...");
} else {
console.log("`_routes.json` not found. Skipping patch...");
Expand Down
13 changes: 0 additions & 13 deletions apps/web/public/_headers

This file was deleted.

2 changes: 2 additions & 0 deletions apps/web/public/_redirects
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Hint Cloudflare to avoid going to the Worker for HTML
/o/* /index.html 200
29 changes: 29 additions & 0 deletions apps/web/src/app/EnrollmentServer/[...rest].ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { APIEvent } from "@solidjs/start/server";
import { env } from "~/env";

async function handler({ request, params }: APIEvent) {
console.log(params.rest);

const url = new URL(env.RUST_URL);
url.pathname = params.rest!;
console.log(url.toString());
const resp = await fetch(url.toString(), {
method: request.method,
headers: request.headers,
body: request.body,
});
const headers = new Headers(resp.headers);
headers.delete("content-encoding"); // SS has a fit if we pass this through
headers.delete("strict-transport-security");
return new Response(resp.body, {
status: resp.status,
statusText: resp.statusText,
headers,
});
}

export const GET = handler;
export const POST = handler;
export const PUT = handler;
export const PATCH = handler;
export const DELETE = handler;
1 change: 1 addition & 0 deletions apps/web/src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const env = withEnv((env) => {
INTERNAL_SECRET: z.string(),
DATABASE_URL: z.string(),
MANAGE_URL: z.string(),
RUST_URL: z.string(),
FROM_ADDRESS: z.string(),
NODE_ENV: z.enum(["development", "production"]).default("development"),
// Emails and other AWS services
Expand Down
1 change: 1 addition & 0 deletions sst.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ export default $config({
INTERNAL_SECRET: INTERNAL_SECRET.result,
DATABASE_URL: $interpolate`https://:${INTERNAL_SECRET.result}@${cloudHost}`,
MANAGE_URL: renderZoneDomain(zone, manageSubdomain),
RUST_URL: cloud.url,
FROM_ADDRESS: $interpolate`Mattrax <${sender}>`,
AWS_ACCESS_KEY_ID: webAccessKey.id,
AWS_SECRET_ACCESS_KEY: webAccessKey.secret,
Expand Down

0 comments on commit f822d32

Please sign in to comment.