Nuxt.js: Make serverMiddleware available when generating static pages

Created on 3 Nov 2019  路  4Comments  路  Source: nuxt/nuxt.js

What problem does this feature solve?

Some server side data APIs are provided as serverMiddleware. These middleware can be accessed both on client side and also on server side in asyncData when either running nuxt start or nuxt dev. This is a quite convenient way to access data needed for pages in asyncData.

Unfortunately none of the serverMiddleware seems to be working during static generation when running nuxt generate.

If the serverMiddleware were accessible during static file generation:

  • The page's asyncData could have access to the initial data. There was no need for providing payload in the generate method in nuxt.config.js.
  • With some logic in the serverMiddleware we could "record" the response to the dist folder in json files for the static files to access them (when no server is available)

I think currently the serverMiddleware are not used by design but I don't know the code enough to know why it is that way.

My current mitigation: start an API server on a different port in the nuxt.config.js. This works but feels unnecessary.

What does the proposed changes look like?

The middleware in serverMiddleware are accessible during static generation.

This feature request is available on Nuxt community (#c9978)
feature-request

Most helpful comment

The PR #6159 should also enable to have access to the serverMiddleware when using nuxt generate :)

All 4 comments

The PR #6159 should also enable to have access to the serverMiddleware when using nuxt generate :)

Still not working for me.

Downloaded the nuxt version 2.14 and set up the target property

serverMiddleware: [
      '~/serverMiddleware/redirect.js',
],

target: 'static'

The redirect file is not called in nuxt generate (while it works in nuxt dev)

// /serverMiddleware/redirect.js
const redirects = [
  { 'from': /\/profile\/?$/, 'to': '/profile/userprofile' },
]

module.exports = function (req, res, next) {
  let url = req.url
  const redirect = redirects.find(r => url.match(r.from))
  if (redirect .to) {
    res.writeHead(301, { Location: redirect .to})
    res.end()
  } else {
    next()
  }
}

This still doesn't work.

I digged current implementation(v2.14.7) and it looks like serverMiddleware is enabled(by calling "nuxt.server.listen(0)") as https://github.com/nuxt/nuxt.js/issues/6648#issuecomment-550322087 said.

The problem is we didn't have a way to know random port(what listen(0) does) of nuxt server instance.
I made hacky(uses process.env) workaround for this issue by writing custom module.
I hope we have more better way to resolve this problem.

https://github.com/subuta/play-with-nuxt-generate/blob/main/modules/nuxt-generate-helper/index.js#L13-L23

SEE: https://github.com/subuta/play-with-nuxt-generate

// Custom module function, that keeps nuxt server instance's port to `process.env`
export default function () {
  // SEE: https://github.com/nuxt/nuxt.js/issues/7597#issuecomment-652961387
  this.nuxt.hook('listen', (server, listener) => {
    // Keep nuxt server instance's listened port in `process.env`.
    process.env.__NUXT_PORT__ = listener.port
  })
  // At custom plugin, inject `process.env.__NUXT_PORT__` value to asyncData's argument 
  this.addPlugin({
    src: path.resolve(__dirname, './plugin.js'),
    options: { getOrigin }
  })
}

// asyncData function of each page.
async asyncData ({ $axios, $origin }) {
  // Custom `$origin` helper(provided by custom plugin.js) will return 
  // `origin` value like this `http://localhost:${__NUXT_PORT__}`.
  const articles = await $axios.$get(`${$origin()}/api/articles?_expand=author`)
  return { articles }
},
Was this page helpful?
0 / 5 - 0 ratings

Related issues

bimohxh picture bimohxh  路  3Comments

mattdharmon picture mattdharmon  路  3Comments

jaredreich picture jaredreich  路  3Comments

pehbehbeh picture pehbehbeh  路  3Comments

VincentLoy picture VincentLoy  路  3Comments