I'm wanting my next-routes to gracefully handle file not found (really route not found) when running from server.js (server side) as well as running on the link side with Link. I've got a solution but it's very bulkly and feels like I'm not doing it the best way I could.
I'm pasting below my pages file (pages/speakerdetail.js) that does handle both server and client correctly but it seems wrong to have to have a custom render method in every file that says "Not Found".
I've also got this running as in example in the repo
https://github.com/pkellner/next-routes-problem
import React, {Component} from 'react';
import {Link} from '../routes'
import Router from 'next/router'
class speakerdetail extends Component {
static async getInitialProps({req,res,query}) {
console.log("getInitialProps speakerdetail");
let statusCode = 200;
let slugSpeaker = '';
let ccYear = '';
if (query && query.slugSpeaker) {
console.log("query.slugSpeaker:" + query.slugSpeaker);
slugSpeaker = query.slugSpeaker;
}
if (query && query.ccYear) {
console.log("query.ccYear:" + query.ccYear);
ccYear = query.ccYear;
}
if (slugSpeaker != 'douglas-crockford-1124' || ccYear != '2018') {
if (req) {
console.log("getInitialProps - res.redirect cause server");
statusCode = 404;
res.statusCode = 404;
} else {
console.log("getInitialProps - router.push cause client")
Router.push('/error404');
}
}
return {
slugSpeaker,
ccYear,
statusCode
};
}
render() {
if (this.props.statusCode == 404) {
return (
<div>Not Found</div>
)
}
return (
<div>
<b>speakerdetail {this.props.ccYear} {this.props.slugSpeaker} {this.props.statusCode}</b>
<hr/>
<Link route='/' >
<a>home</a>
</Link>
</div>
);
}
}
speakerdetail.propTypes = {};
speakerdetail.defaultProps = {};
export default speakerdetail;
Instead of manually checking every params passed to the page, it is better to control from your server.js
file:
const next = require('next');
const routes = require('./routes');
const app = next({dev: process.env.NODE_ENV !== 'production'});
const handler = routes.getRequestHandler(app);
// With express
const express = require('express');
app.prepare().then(() => {
const srv = express();
srv.get('/:year/:slugSpeaker', (req, res) => {
const { year, slugSpeaker } = req.params;
return app.render(req, res, `/speakerdetail`, {
year,
slugSpeaker,
});
});
srv.use(handler).listen(3000)
});
Then you can try to open url with incorrect data, it will automatically redirect to 404 page.
Reference: NextJS with custom-server-express
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With