Writing koa/nuxt applications

hiswe
ITNEXT
Published in
5 min readOct 23, 2018

--

You’re ready to make your new application.
You take Vue 2 as your framework

But you want your application to be:

So you decide to make a Universal Web Application with Nuxt 2 & Koa 2
It will:

  • fasten the first rendering
  • be able to run without JS activated on the client side

Notes:

  • You will need to be familiar with Koa/Nuxt.
  • Be aware that both Nuxt and Koa use the concepts of context (ctx) & middleware.
    I’ve tried to differentiate them as much as I could in the following post, but if you’re confused reread carefully and try to sort it out 😅
  • You can find a working example of what I’m talking next in the koa-nuxt-example repository

Shaped for express

Because express.js is the most commonly used Node.js server framework, most of the UWA frameworks render function are shaped for it.

This means that in express, Nuxt integration came out of the box.
You just need to call it like any express middleware:

Since we want to use Koa, we will need to make our own middleware.
No need to think a lot about integration since this has already been solved but the Nuxt community

This will work perfectly if you’re only interested in server rendering.

Handling POST

Let’s say we want to be able to post a form.

  • First we will install/use koa-router and koa-body
  • Then with those, we will be able to handle our POST action
  • And we might want to do a database call inside it (doSomethingAsync in the example)

This is kind of ok:

  • we can now post some data
  • redirect to / where Nuxt will handle the markup

JSON response can be added by later by

  • checking what’s the request Content-Type header (ctx.is('application/json'))
  • don’t redirect
  • send back the appropriate response

Handling errors

We should write an error middleware.
It will make sure that if something went wrong, our application won’t crash.

To catch all the things, it will be our first middleware.

So now if anything throw (DB call, JSON parsing…) we will render a page with the error printed.

Handling Server data with Nuxt

We also should send back some data validation to the user form.

In order to display any validation in the Nuxt application we will need to:

  • persist data between our post route and the redirection
  • pass those data down to the Nuxt application
  • do something with it

Koa-session

The most common way to handle data between routes is with sessions.
We’ll use koa-session for this.

The installation guide is pretty self explanatory.
This will add a ctx.session object where we can pass any kind of information.

Here is the different steps to follow:

  • Validate our form
  • Add the validation to the session
  • Pass it to Nuxt
    – Because Nuxt doesn’t use the Koa ctx but use req & res, copy our session information into those objects.
    – This will be done in a Koa middleware just before the nuxt-rendering middleware
  • Integrate it in the Nuxt application by either using:
    – a Nuxt middleware
    – the nuxtServerInit for Vuex integration
    Right now let’s start with nuxtServerInit.
  • …and since now all is in the Vue realm, just use our Vue Components.

In the store/index.js

And that’s it, we now have a Vuex store updated with our server validation.
Use the mapState helper in our Vue component to access it.

Can’t set headers after they are sent

Right now, we set the validation on our POST route, and never update it again.

It means that the validation will be persisted until the user send a good form.
So if the user change page and go back to the form, the application will still display the last validation result.
This isn’t right, we should clear the validation once displayed.

This should be easy by updating our Koa middleware that link our session to Nuxt.

⚠️ But this won’t work

You’ll find in the server logs a Can't set headers after they are sent.
The problem comes from the nuxtMiddleware & how it bypasses the regular Koa flow.

Usually we set a ctx.body and all the previous middleware will continue their work.

But that’s what happen here

To fix that we need to make sure that our headers are set before the Nuxt middleware.

autoCommit: false to the rescue

Koa-session lets us send the headers manually with the manuallyCommit() method

So we have to refactor our server code like this:

This will solve our problem ❤️
We just have now to remember calling manuallyCommit() every time we update the session… 😶

Displaying all errors with Nuxt

There is one last thing we have to take care of.
Right now our handleError middleware will make Koa show the error.
But in Nuxt support an error layout and we should take advantage of it.

To do this we’ll need to modify our handleError middleware:

  • set the error to the ctx.req object (Remember, Nuxt still only work with req & res)
  • call Nuxt to render the page inside our handleError middleware
  • write a Nuxt middleware that will render the error page by calling nuxtContext.error

And for the Nuxt part:

  • create a middleware/handle-server-errors.js file
  • reference it in the nuxt.config.js

Conclusion

Making Nuxt working with Koa isn’t as smooth as with Express.
Still I prefer working with Koa, and with a little more boilerplate everything’s fine.

I’m sure there is room for improvements, but it’s working for me.
The downside is mainly more boilerplate code and handling session updates manually.

Most of the code here isn’t necessary if

  • you just want some basic server rendering
  • you don’t need to support any kind of session

Supporting asynchronous code should be easy

As a reminder you can find a full example here

💚 Nuxt 💙 KOA

Originally published at hiswe.github.io.

--

--