Goal: I would like to achieve github style routing, where
abcd
ingithub.com/abcd
could resolve to a user profile page or a team page.
I currently have a version that sort of works (see below). Unfortunately I am occasionally getting a white page flash when navigating between 2 dynamic routes.
My server file looks like:
const express = require('express');
const next = require('next');
const { parse } = require('url');
const resolveRoute = require('./resolveRoute');
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const nextApp = next({
dev,
});
const nextHandle = nextApp.getRequestHandler();
const STATIC_ROUTES = [
'/about',
'/news',
'/static',
];
const DYNAMIC_ROUTE_MAP = {
user: '/[user]',
team: '/teams/[team]',
};
nextApp.prepare().then(() => {
const server = express();
server.get('*', async (req, res) => {
// pass through next routes
if (req.url.indexOf('/_next') === 0) {
return nextHandle(req, res);
}
// pass through static routes
if (
req.url === '/' ||
STATIC_ROUTES.map(route => req.url.indexOf(route) === 0).reduce(
(prev, curr) => prev || curr,
)
) {
return nextHandle(req, res);
}
// try to resolve the route
// if successful resolves to an object:
// { type: 'user' | 'team' }
const resolvedRoute = await resolveRoute(req.url);
if (!resolvedRoute || !resolvedRoute.type) {
console.error(' Unable to resolve route...');
return nextHandle(req, res);
}
// set query
const { pathname } = parse(req.url);
const paths = pathname.split('/').filter(path => path.length > 0);
const query = {
[resolvedRoute.type]: paths.length > 0 ? paths[0] : null,
};
// render route
return nextApp.render(
req,
res,
DYNAMIC_ROUTE_MAP[resolvedRoute.type],
query,
);
});
server.listen(port, err => {
if (err) throw err;
console.log(` Ready on http://localhost:${port}`);
});
});
I'm wondering if there is a better way to handle this or if I need to move away from NextJS.