A. Some file are expected to be found at "/"
You have this error because browsers expect some files to be served from the root of the server, including:
/manifest.json
/sitemap.xml
/favicon.ico
/robots.txt
/browserconfig.xml
/site.webmanifest
While the majority of these paths can be set with meta tags, older browsers just ignore them and error if these exact file names are not served.
B. Configure alternative paths and use NextJS static file
At the time of writing, there is ongoing work for supporting offline in NextJS. But it's not ready yet.
If you don't need to support older browsers and you don't want advanced SEO, you can use NextJS's Head
component (see documentation) to define the manifest.json
path like you would for any NextJS static file:
import Head from "next/head"
export default () => (
<Head>
<link rel="manifest" href="/static/manifest.json" />
<link rel="manifest" href="/static/site.webmanifest" />
<link rel="shortcut icon" href="/static/favicon.ico"
</Head>
)
Please note that robots.txt
cannot be serve from a subdirectory (source), so this solution is not a good fit if you need to define this file.
C. Serve these files like expected
The proper solution would be to serve these files from your express server like so
const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')
const { join } = require('path')
const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare()
.then(() => {
createServer((req, res) => {
const parsedUrl = parse(req.url, true)
const rootStaticFiles = [
'/manifest.json',
'/sitemap.xml',
'/favicon.ico',
'/robots.txt',
'/browserconfig.xml',
'/site.webmanifest',
]
if (rootStaticFiles.indexOf(parsedUrl.pathname) > -1) {
const path = join(__dirname, 'static', parsedUrl.pathname)
app.serveStatic(req, res, path)
} else {
handle(req, res, parsedUrl)
}
})
.listen(port, (err) => {
if (err) throw err
console.log(`> Ready on http://localhost:${port}`)
})
})
Note: This code directly comes from the NextJS examples repository