Next.js: Running statically exported bundle on a sub-folder of the URL

Created on 30 Dec 2017  路  5Comments  路  Source: vercel/next.js

I feel like I might be missing something obvious, but I'm having trouble running my statically exported Next.js app on a sub-folder. Or in other words, this is what I basically want to do:

  1. Run next build && next export -o dist to create a <proj_root>/dist directory with my static bundle.
  2. The user's browser requests should have the following behaviour:

    • http://example.com/portal will serve /dist/index.html

    • http://example.com/portal/orders will serve /dist/orders/index.html

    • this tag: <img src="/static/image.jpg" /> will serve up /dist/static/image.jps

  • [x] I have searched the issues of this repository and believe that this is not a duplicate.

The problem

The problem with the naive approach is that the image request:

<img src="/static/image.jpg" />

will end up trying to make a request to:

http://example.com/static/image.jpg

instead of:

http://example.com/portal/static/image.jpg

assetPrefix

One way of making this work is to add the following to my next.config.js file:

assetPrefix: isProd ? "/portal" : ""

But this means that if the NGINX configuration ever changes, I'll have to update the assetPrefix and deploy accordingly.

This seems like a cross-cutting concern to me, especially since I was under the impression that a static bundle should be exportable with relative paths that would make it work anywhere.

The router (NGINX in this case) is supposed to do all the work, but alas I don't have much experience with NGINX (and on this project the client has not disclosed his nginx.conf to me).

Finally

Of course, this would all be easily solved if we used http://portal.example.com instead of http://example.com/portal, but this is not something I have a say in.

Is there a recipe for making this work? Perhaps an example nginx.conf that works for this use-case? Or is this something that must be set in the assetPrefix. As far as I'm aware, I thought the assetPrefix was for CDNs primarily, and not for this use-case.

All 5 comments

Someone suggested the following nginx configuration:

server {
  # port, server name here, etc.
  location = / {
    index index.html;
  }
  location / {
    try_files /portal/$uri /portal/$uri.html /portal/index.html $uri $uri.html $uri/ /index.html;
  }
}

... which I don't really understand, but example.com/portal properly serves up /dist/index.html.

But it breaks Next.js's routing. For example, if I tried to do Router.push('/orders') inside index.js, I would get pushed from example.com/portal to example.com/orders instead of example.com/portal/orders.

@adrianmcli did you have any luck with this issue? I'm facing the same exact problem so I'm curious if you found some sort of solution.

We switched to http://portal.example.com but I am still interested in a solution as well.

I have a very valid use-case for needing to load NextJS via file:// URLs (performance), ideally without a server. A plan B is serving the out folder via a regular server (npm i serve, python -m SimpleHTTPServer... etc. #2093), but even that has issues.

Any advice towards the most lightweight method of pre-rendering and then exporting the app to be run locally would be greatly appreciated @timneutkens, I've got a week to make this happen 馃憤

Closing this in favor of tracking it here: #4998

Was this page helpful?
0 / 5 - 0 ratings