vercel/next-plugins

style.css href when using a custom Express server

colinrobertbrooks opened this issue ยท 11 comments

I'm using a custom Express server with next.js in a subdirectory. I have installed @zeit/next-css and added next.config.js and pages/_document.js per the README; however, /_next/static/style.css returns a 404. I've confirmed that the file is being built to .next/static/style.css. I've also tried to ping it at a few different URLs (e.g. /_next/-/static/style.css), but I can't find where it's being served. This is all true in both development and production. Do I need to configure the static folder in my custom server.js (code below)?

const express = require('express');
const next = require('next');

const dev = process.env.NODE_ENV !== 'production';
const app = next({ dir: './client', dev });
const handle = app.getRequestHandler();

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

    // custom routes
    server.get('/s/:id', (req, res) => {
      const actualPage = '/show';
      const queryParams = { id: req.params.id };
      app.render(req, res, actualPage, queryParams);
    });

    // default route
    server.get('*', (req, res) => {
      return handle(req, res);
    });

    server.listen(3000, err => {
      if(err) throw err;
      console.log('> Ready on http://localhost:3000');
    });
  })
  .catch(ex => {
    console.error(ex.stack);
    process.exit(1);
  });

I have the same problem, only production.
/_next/static/style.css returns a 404.

I've also tried to ping it at a few different URLs
/src/_next/static/style.css
./src/_next/static/style.css

Just tried and I can't reproduce based on your code. Can you provide a minimal reproduction ๐Ÿ‘

@timneutkens, thanks for taking a look. See here.

const app = next({ dir: './client', dev });

You're starting your app with ./client, but the server is inside the client folder. That's the reason.

If you use . it'll work

Changing the line to

const app = next({ dir: '.', dev });

or

const app = next({ dev });

both cause the index page endpoint to throw a 404. I'm trying to run next inside the client folder.

I added the following to server.js:

server.use('/static', express.static(path.join(__dirname, '.next/static')));

and changed the link in pages/_document.js to:

<link rel="stylesheet" href="/static/style.css" />

which works in development and production.

I also configured static file serving and that still works with this configuration in development and production as well.

Any other potential watchouts?

TLDR - this issue was fixed here

my setup

I was running into all of the same issues as @colinrcummings - after a lot of digging around there seems to be a discrepancy between where the distDir or dist directory gets place relative to a custom src directory.

Heres my setup:

// ./next.config.js
const withCSS = require('@zeit/next-css')

const opts = {
  distDir: '../dir', 
}

module.exports = withCSS(opts)
// src/server.js 
// I start my server with `NODE_PATH='./src' node src/server.js`
const next = require('next')

const port = parseInt(process.env.PORT, 10) || 3005
const express = require('express')
const expressRoutes = require('./express-routes')
const bodyParser = require('body-parser')

const dev = process.env.NODE_ENV !== 'production'
const app = next({ dir: 'src', dev, quiet: false })

const runServer = () => {
  const handle = app.getRequestHandler()
  const server = express()

  server.use(bodyParser.json())

  app.prepare()
    .then(() => {
      expressRoutes.register(app, server, handle)

      server.listen(port, (err) => {
        if (err) throw err
        /* eslint-disable no-console */
        console.log(`> Ready on http://localhost:${port}`)
      })
    })
}

runServer()

Finally, I had to track down the 404 for the static output - debugging a bunch, I found that the path resolutions inside of next/server were not relative to the dist directory.

https://github.com/zeit/next.js/blob/5.0.0/server/index.js#L243-L246

Changing it to

'/_next/static/:path*': async (req, res, params) => {
  const p = join(this.dir, this.dist, 'static', ...(params.path || []))
  await this.serveStatic(req, res, p)
},

Did the trick for me, but I'm using a local copy of next (5.0.0).

I'm not sure when patch I mentioned above is planned for stable release.

In the meantime you can add to your package.json:

    "next": "https://github.com/zeit/next.js.git#5.0.1-canary.16",

and run npm run build from node_modules/next manually until there is new package available in npm.

Using ^6.0.0-canary.3and the code is updated as lfender6445 suggested above, however the style.css file is still not found.

EDIT: Nevermind, I was using Sass but I wasn't importing the file in the any pages document.

Try to use "/static/css"

maybe you are using "static/css"

Wrong > <link href="static/css/responsive.css" rel="stylesheet"/>
Correct > <link href="/static/css/responsive.css" rel="stylesheet"/>