Search code examples
reactjsurl-routingnext.js

Endpoint returns 404 when using custom Express server


I have a Next.js app with two pages. My structure looks like the following:

/pages
    /index.js
    /city.js

I've created a custom server so that if the user goes to anything other than the home page it should render city.js. For example if you go to myapp.com/phl then the url should stay myapp.com/phl but it should render city.js. The same applies if you go to myapp.com/stl.

Here's my custom server:

const express = require('express');
const next = require('next');
const url = require('url');
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handler = app.getRequestHandler();

app.prepare()
    .then(() => {
        const server = express();

        server.get('*', (request, response) => {
            return handler(request, response);
        });

        server.get('/:airportCode', (request, response) => {
            console.log('hello from the server');
            app.render( request, response, '/city', { ...request.query, ...request.params } );
        });

        server.listen(3000, error => {
            if (error) throw error;

            console.log('> Ready on http://localhost:3000');
        });
    })
    .catch(exception => {
        console.error(exception.stack);
        process.exit(1);
    });

When I visit the home page it renders that page fine, but when I go to https://myapp.com/phl I get a 404. Am I missing something?


Solution

  • You need to switch up your page handler with the asterisk page handler:

    const express = require('express');
    const next = require('next');
    const url = require('url');
    const dev = process.env.NODE_ENV !== 'production';
    const app = next({ dev });
    const handler = app.getRequestHandler();
    
    app.prepare()
        .then(() => {
            const server = express();
    
            server.get('/:airportCode', (request, response) => {
                console.log('hello from the server');
                app.render( request, response, '/city', { ...request.query, ...request.params } );
            });
    
            server.get('*', (request, response) => {
                return handler(request, response);
            });
    
            server.listen(3000, error => {
                if (error) throw error;
    
                console.log('> Ready on http://localhost:3000');
            });
        })
        .catch(exception => {
            console.error(exception.stack);
            process.exit(1);
        });

    The function of asterisk is like a fallback for any path that isn't handled by the previous function.