Nuxt.js — Error Pages, Async, and Request Data

John Au-Yeung - Jan 19 '21 - - Dev Community

Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62

Subscribe to my email list now at http://jauyeung.net/subscribe/

Nuxt.js is an app framework that’s based on Vue.js.

We can use it to create server-side rendered apps and static sites.

In this article, we’ll look at how to add error pages, get async data, and get request data with Nuxt.js.

Error Page

We can add an error page to our Nuxt app by putting pages files in the layouts folder.

For example, if we want to show a page when we get a 404 error, we add a layouts/error.js file:

<template>
  <div>
    <h1 v-if="error.statusCode === 404">Page not found</h1>
  </div>
</template>

<script>
export default {
  props: ["error"],
};
</script>
Enter fullscreen mode Exit fullscreen mode

It takes an error prop and we can check the statusCode property for the error status code.

Pages

Pages have special attributes and functions to make the development of our universal app.

For example, our pages may look like:

<template>
  <div>hello {{ name }}</div>
</template>

<script>
export default {
  asyncData(context) {
    return { name: "world" };
  },
  fetch() {
    //...
  },
  head() {
    return { foo: "bar" };
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode

The asyncData method lets us set the state before loading the component.

The returned object will be merged with our data object.

The fetch method lets us fill the store before rendering the page.

head lets us set the meta tags for the page.

loading prevents a page from automatically calling this.$nuxt.$loading.finish() as we enter it and this.$nuxt.$loading.start() as we leave it.

This lets us manually control the behavior.

transition defines a specific transition for the page.

scrollToTop is a boolean that specifies if we want to scroll to the top before rendering the page.

validate is a validator function for dynamic routes.

middleware defines the middleware for the page.

Async Data

We can use the asyncData method for getting data.

If we use Axios interceptors in our code, then we have to create an instance of it first.

For example, we can write:

import axios from 'axios'
const myAxios = axios.create({
  // ...
})
myAxios.interceptors.response.use(
  function (response) {
    return response.data
  },
  function (error) {
    // ...
  }
)
Enter fullscreen mode Exit fullscreen mode

In our asyncData method, we can return a promise with it.

For example, we can write:

<template>
  <div>{{ title }}</div>
</template>

<script>
import axios from "axios";

export default {
  async asyncData({ params }) {
    const { data } = await axios.get(
      `https://jsonplaceholder.typicode.com/posts/${params.id}`
    );
    return { title: data.title };
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode

We have the asyncData method that takes an object with the params property.

It has the URL parameters for our page.

Then we can use axios to get the data we want and return the resolved value.

The resolved object can be retrieved from our component.

The Context

The context parameter for asyncData also has the req and res properties.

req has the request object.

And res has the response.

We use the process.server to check if the page is server-side rendered before using the request data.

To do that, we write:

pages/hello.vue

<template>
  <div class="container">{{host}}</div>
</template>

<script>
export default {
  async asyncData({ req, res }) {
    if (process.server) {
      return { host: req.headers.host };
    }
    return {};
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode

If process.server is true , then we can use the req object to get the request data.

Conclusion

We can get request data with Nuxt in our pages.

Also, we can create our own error page.

And we can initial our page with async data.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .