ayncData
and fetch
methods to fetch data on the server-side using Axios and the
differences between the two methods. Finally, we will learn how to add
authentication to our application using the Auth module.In this tutorial, we’re going to learn how to use the Axios module and how to make a request on the server-side using asyncData and fetch. These two methods make a request on the server-side but they have some differences which we’re also going to cover. Finally, we’ll learn how to perform authentication and secure pages/routes using the auth module and auth middleware.
This article requires basic knowledge of Nuxtjs and Vuejs as we’ll be building on top of that. For those without experience with Vuejs, I recommend you start from their official documentation and the Nuxt official page before continuing with this article.
What Is The Nuxt.js Axios Module?
According to the official Documentation,“It is a Secure and easy Axios integration with Nuxt.js.”Here are some of its features:
- Automatically set base URL for client-side & server-side.
- Proxy request headers in SSR (Useful for auth).
- Fetch Style requests.
- Integrated with Nuxt.js Progressbar while making requests.
npm
or yarn
.YARN
NPM
Add it into your
nuxt.config.js
file:The
modules
array accepts a list of Nuxt.js modules such as dotenv, auth and in
this case, Axios. What we’ve done is to inform our application that we
would be using the Axios module, which we reference using @nuxtjs/axios
. This is then followed by the axios
property which is an object of configurations like the baseURL for both client-side and server-side.Now, you can access Axios from anywhere in your application by calling
this.$axios.method
or this.$axios.$method
. Where method can be get
, post
, or delete
.Making Your First Request Using Axios
After cloning the repo and opening the
start
folder, we would need to install all our packages in the package.json
file so open your terminal and run the following command:Once that is done, we can start our app using the
npm run dev
command. This is what you should see when you go to localhost:3000
.The next thing we have to do is to create a
.env
file in
the root folder of our application and add our API URL to it. For this
tutorial, we’ll be using a sample API built to collect reports from
users.This way, we do not have to hard code our API into our app which is useful for working with two APIs (development and production).
The next step would be to open our
nuxt.config.js
file and add the environmental variable to our axios config that we added above.baseURL
for both our client-side and server-side requests whenever we use this Axios module.Now, to fetch a list of reports, let us open the
index.vue
file and add the following method to the script section.What we have done is to create an async function that we call
getIncidents()
and we can tell what it does from the name — it fetches a list of incidents using the Vuex store action method this.$store.dispatch
. We assign the response from this action to our incidents property so we can be able to make use of it in the component.We want to call the
getIncidents()
method whenever the component mounts. We can do that using the mounted
hook.mounted()
is a lifecycle hook
that gets called when the component mounts. That will cause the call to
the API to happen when the component mounts. Now, let us go into our index.js
file in our store and create this action where we’ll be making our Axios request from.Here, we created the action called
getIncidents
which is an async function, then we await a response from the server and return this response. The response from this action is sent back to our getIncidents()
method in our index.vue
file.If we refresh our application, we should now be able to see a long list of incidents rendered on the page.
We have made our first request using Axios but we won’t stop there, we are going to be trying out
asyncData
and fetch
to see the differences between them and using Axios.AsyncData
AsyncData fetches data on the server-side and it’s called before loading the page component. It does not have access tothis
because it is called before your page component data is created. this
is only available after the created
hook has been called so Nuxt.js automatically merges the returned data into the component’s data.Using
asyncData
is good for SEO because it fetches your site’s content on the server-side and also helps in loading content faster.
Note that asyncData
method can only be used in the pages folder of your application as it would not work in the components folder. This is because asyncData
hook gets called before your component is created.Let us add
asyncData
to our index.vue
file and observe how fast our incidents data loads. Add the following code after our components property and let us get rid of our mounted hook.Here, the
asyncData
method accepts a property from the context $axios
.
We use this property to fetch the list of incidents and the value is
then returned. This value is automatically injected into our component.
Now, you can notice how fast your content loads if you refresh the page
and at no time is there no incident to render.Fetch
The Fetch method is also used to make requests on the server-side. It is called after the created hook in the life cycle which means it has access to the component’s data. Unlike theasyncData
method, the fetch method can be used in all .vue files and be used with the Vuex store. This means that if you have the following in your data function.You can easily modify id or gender by calling
this.id
or this.gender
.Using Axios As A Plugin
During the process of development with Axios, you might find that you need extra configuration like creating instances and interceptors for your request so your application can work as intended and thankfully, we can do that by extending our Axios into a plugin.To extend
axios
, you have to create a plugin (e.g. axios.js) in your plugins
folder.$axios
, store
and redirect
which we would use in configuring the plugin. The first thing we do is to listen for an error with a status of 500
using $axios.onError
and redirect the user to the login page.We also have an interceptor that intercepts every request response we make in our application checks if the status of the response we get is
200
. If that is true we proceed and check that there is a response.request.responseURL
and if it includes login. If this checks out to be true, we then send
this response using our store’s dispatch method where it then mutated in
our state.Add this plugin to your
nuxt.config.js
file:After doing this, your Axios plugin would intercept any request you make and check if you have defined a special case for it.
Introduction To The Auth Module
The auth module is used for performing authentication for your Nuxt application and can be accessed from anywhere in your application using$this.auth
. It is also available in fetch
, asyncData
, middleware
and NuxtInitServer
from the context object as $auth
.The
context
provides additional objects/params from Nuxt to Vue components and is
available in special nuxt lifecycle areas like those mentioned above.To use the auth module in your application, you would have to install it using
yarn
or npm
.YARN
NPM
Add it to your
nuxt.config.js
file.The auth property accepts a list of properties such as
strategies
and redirect
. Here, strategies
accepts your preferred authentication method which can be:local
For username/email and password-based flow.facebook
For using Facebook accounts as a means of authentication.Github
For authenticating users with Github accounts.Google
For authenticating users with Google accounts.- Auth0
- Laravel Passport
login
Users would be redirected to this link if login is required.logout
Users would be redirected here if after logout current route is protected.home
Users would be redirected here after login.
nuxt.config.js
file.Please note that the
auth
method works best when there is a user
endpoint provided in the option above.Inside the
auth
config object, we have a redirect
option in which we set our login route to /login
, logout route to /
and home route to /my-reports
which would all behave as expected. We also have a tokenType
property which represents the Authorization type in the header of our Axios request. It is set to Bearer
by default and can be changed to work with your API.For our API, there is no token type and this is why we’re going to leave it as an empty string. The
tokenName
represents the Authorization name (or the header property you want to
attach your token to) inside your header in your Axios request.By default, it is set to
Authorization
but for our API, the Authorization name is x-auth
. The autoFetchUser
property is used to enable user fetch object using the user
endpoint property after login. It is true
by default but our API does not have a user
endpoint so we have set that to false
.For this tutorial, we would be using the local strategy. In our strategies, we have the local option with endpoints for login, user and logout but in our case, we would only use the
*login*
option because our demo API does not have a *logout*
endpoint and our user object is being returned when *login*
is successful.Note: The
auth
module does not have a register endpoint option so that means we’re
going to register the traditional way and redirect the user to the login
page where we will perform the authentication using this.$auth.loginWith
. This is the method used in authenticating your users. It accepts a ‘strategy’ (e.g local
) as a first argument and then an object to perform this authentication with. Take a look at the following example.Using The Auth Module
Now that we have configured our auth module, we can proceed to our registration page. If you visit the/register
page, you should see a registration form.Let us make this form functional by adding the following code:
Here, we have an async function called
registerUser
which is tied to a click event in our template and makes an Axios request wrapped in a try/catch block to an endpoint /user/create
. This redirects to the /login
page and notifies the user of a successful registration. We also have a
catch block that alerts the user of any error if the request is not
successful.If the registration is successful, you would be redirected to the login page.
Here, we’re going to make use of auth authentication method
this.$auth.loginWith('local', loginData)
after which we would use the this.$auth.setUser(userObj)
to set the user in our auth
instance.To get the login page working, let’s add the following code to our
login.vue
file.We created an async function called
logIn
using the auth method this.$auth.loginWith('local, loginData)
. If this login attempt is successful, we then assign the user data to our auth instance using this.$auth.setUser(userInfo)
and redirect the user to the /my-report
page.You can now get user data using
this.$auth.user
or with Vuex using this.$store.state.auth.user
but that’s not all. The auth
instance contains some other properties which you can see if you log in or check your state using your Vue dev tools.If you log
this.$store.state.auth
to the console, you’ll see this:The
auth
instance contains a loggedIn
property that is useful in switching between authenticated links in the
nav/header section of your application. It also contains a strategy
method that states the type of strategy the instance is running (e.g
local).Now, we will make use of this
loggedIn
property to arrange our nav
links. Update your navBar
component to the following:auth.loggedIn
to display the appropriate links depending on the authentication status. We have a logout button that has a click
event with a logOut()
function attached to it. We also display the user’s email gotten from
the auth property which is accessed from our Vuex store using the mapState
method which maps our state auth to the computed property of the nav component. We also have a logout
method that calls our Vuex action logOut
and redirects the user to the login
page.Now, let us go ahead and update our store to have a
logOut
action.The
logOut
action calls the auth logout
method which clears user data, deletes tokens from localStorage
and sets loggedIn
to false
.Routes like
/my-reports
and report-incident
should not be visible to guests but at this point in our app, that is not the case. Nuxt does not have a navigation guard that can protect your routes, but it has is the auth middleware. It gives you the freedom to create your own middleware so you can configure it to work the way you want.It can be set in two ways:
- Per route.
- Globally for the whole app in your
nuxt.config.js
file.
auth
middleware works with your auth
instance so you do not need to create an auth.js
file in your middleware folder.Let us now add this middleware to our
my-reports.vue
and report-incident.vue
files. Add the following lines of code to the script section of each file.Now, our application would check if the user trying to access these routes has an
auth.loggedIn
value of true
. It’ll redirect them to the login page using our redirect option in our auth config file — if you’re not logged in and you try to visit either /my-report
or report-incident
, you would be redirected to /login
.This page is for adding incidents but that right now the form does not send incident to our server because we are not making the call to the server when the user attempts to submit the form. To solve this, we will add a
reportIncident
method which will be called when the user clicks on Report. We’ll have this in the script section of the component. This method will send the form data to the server.
Update your report-incident.vue
file with the following:v-model
. We also have a submit
button with a click event. In the script section, we have a reportIncident
method that collects all the information provided in the form and is sent to our server using FormData because the API is designed to also accept images and videos.This
formData
is attached to a Vuex action using the dispatch method, if the request is successful, you get redirected to /my-reports
with a notification informing you that this request was successful
otherwise, you would be notified of an error with the error message.At this point, we don’t have
reportIncident
action in our store yet so in your browser console, you would see an error if you try to click submit on this page.To fix this, add the reportIncident action your
index.js
file.Here, we have a
reportIncident
function that takes in an empty context object and the data we’re sending from our form. This data is then attached to a post
request that creates an incident and returns back to our report-incident.vue
file.At this point, you should be able to add a report using the form after which you would be redirected to
/my-reports
page.This page should display a list of incidents created by the user but right now it only shows what we see above, let’s go ahead to fix that.
We’re going to be using the
fetch
method we learned about to get this list. Update your my-reports.vue
file with the following:Here, we use
fetch
method to get user-specific incidents and assign the response to our incidents array.At this point, we would notice a difference in how
fetch
method and asyncData
loads our data.Conclusion
So far, we have learned about the Axios module and all of its features. We have also learned more about asyncData, and how we can fetch both of them together despite their differences. We’ve also learned how to perform authentication in our application using the auth module and how to use the auth middleware to protect our routes. Here are some useful resources that talk more about all we’ve covered.- Getting started with meta tags in Nuxjs.
- Using the dotenv module in Nuxt.
- Using Fetch in your Nuxt app.
- Getting started with asyncData.
Resources
- “Auth Module,” NuxtJS.org
- “Axios Module: Introduction,” NuxtJS.org
FormData
, MDN web docs- “API: The
asyncData
Method,” NuxtJS.org - “The Vue Instance: Lifecycle Diagram,” VueJS.org
- “Understanding How
fetch
Works In Nuxt 2.12,” NuxtJS.org