Last active
May 27, 2022 04:38
-
-
Save caub/4ddbe7ed7642fcaca91553360c37ee91 to your computer and use it in GitHub Desktop.
Next static
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import Html from '../components/html'; // wraps pages into <html> and some common layout | |
// you might want a webpack.config.js at least for styles | |
// typically we use a sass loader, and also @emotion/react in our components | |
// Html will take care to add <link> for built ./build/**/*.css | |
// and <script> for built ./build/**/*.js if any, you might even inline it <script>{content}</script> if short | |
// It's also possible to build css/js assets per page, we didn't do that | |
export async function getServerSideProps({ req }) { | |
// do stuff | |
return { req }; | |
} | |
export default function NotFound(props) { | |
return ( | |
<Html {...props}> | |
<h2 className="text-center">Not found</h2> | |
</Html> | |
) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const express = require('express'); | |
const { renderToStaticMarkup } = require('react-dom/server'); | |
const { createElement } = require('react'); | |
const fs = require('fs'); | |
require('@babel/register')({ only: ['pages', 'components'].map(n => __dirname + '/' + n) }); // uses .babelrc as well | |
const app = express().disable('x-powered-by'); | |
// ... production stuff like https redirect, compression | |
app.use(express.static(__dirname + '/build', process.env.NODE_ENV === 'production' && { | |
redirect: false, | |
index: false, | |
maxAge: '30d', | |
})); | |
// ... production security headers | |
async function renderPage(page, params) { | |
const component = require(`./pages/${page}`); | |
const componentProps = await component.getServerSideProps?.(params); | |
if (componentProps === null) return null; // used for 404's | |
const app = createElement(component.default, { ...params, ...componentProps }); | |
return `<!DOCTYPE html>${renderToStaticMarkup(app)}`; | |
} | |
// custom dynamic pages | |
app.get('/blog/:id', async function (req, res, next) { | |
try { | |
const content = await renderPage('blog/:id.js', { req, id: req.params.id }); | |
if (!content) return next(); | |
res.send(content); | |
} catch (err) { | |
if (!process.env.NODE_ENV) console.error(err); | |
res.sendStatus(500); | |
} | |
}); | |
// regular pages | |
app.get('*', async function (req, res) { | |
const path = new URL(req.url, 'file:').pathname.slice(1).replace(/\/$/, ''); // trim leading / and trailing / | |
const found = fs.existsSync(`./pages/${path}.js`) | |
|| fs.existsSync(`./pages${path ? '/' + path : ''}/index.js`); | |
try { | |
res.status(found ? 200 : 404).send(await renderPage(found ? path : '404', { req })); | |
} catch (err) { | |
if (!process.env.NODE_ENV) console.error(err); | |
res.sendStatus(500); | |
} | |
}); | |
// ... express error middleware | |
app.listen(process.env.PORT || 3000); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment