UNPKG

@platform/react.ssr

Version:

A lightweight SSR (server-side-rendering) system for react apps bundled with ParcelJS and hosted on S3.

67 lines (58 loc) 1.94 kB
import { parse as parseUrl } from 'url'; import { t, fs } from './common'; const CACHE = { 'Cache-Control': `s-maxage=5, stale-while-revalidate` }; export function init(args: { router: t.IRouter; getManifest: t.GetManifest }) { const { router, getManifest } = args; /** * [GET] resource. */ router.get('*', async (req) => { // Load the manifest. const manifest = await getManifest(); if (!manifest.ok) { const status = manifest.status; const message = 'Manifest could not be loaded.'; return { status, data: { status, message } }; } // Retrieve the site definition. const host = req.headers.host; const hostname = (host || '').split(':')[0]; const site = manifest.site.byHost(hostname); if (!site) { const status = 404; const message = `A site definition for the domain '${hostname}' does not exist in the manifest.`; return { status, data: { status, message } }; } // Check if there is a direct route match and if found "server-side-render" the HTML. const url = parseUrl(req.url || '', false); const route = site.route(url.pathname || ''); const ext = fs.extname(url.pathname || ''); // NB: an extension indicates an asset resource, not the entry HTML. if (route && !ext) { const entry = await route.entry(); if (entry.ok) { return { headers: CACHE, data: entry.html, }; } else { const { status, url } = entry; const message = `Failed to get entry HTML from CDN.`; return { status, headers: CACHE, data: { status, message, url }, }; } } // Redirect the resource-request to S3. const location = site.redirectUrl(url.pathname || ''); if (location) { return { status: 307, data: location, }; } // No matching resource. return undefined; }); }