Subdomains with Nuxt.js

This article covers subdomains routing implementation using Nuxt.js and @nuxtjs/router.

A big birdhouse with many entrances

Why subdomains are useful?

Let’s say you want to create a multi-tenants app, something similar to heroku, or google app engine service. You can implement some custom path for each service, so they will look something like this:

Or you can implement it with subdomains approach:

As you can see, the second approach is way more customer friendly, because all service related data is being encapsulated inside this custom subdomain. Not mentioning how easy it will be to assign a custom domain to any of the subdomains.

To those who are coming from a Laravel’s world this issue might seem not that complicated. But in Nuxt world it requires some workaround. The first problem you face is lack of router exposure, so there is no easy way to override standard routing.

Luckily there is a @nuxtjs/router module, which will help us inject our custom logic. At a glance our plan has just four simple steps:

  1. Add router npm package.
  2. Create custom logic inside route.js file.
  3. Create subdirectories for root and subdomain pages.
  4. Implement host logic on our subdomain’s index page.

Adding @nuxtjs/router to your app

Let’s start by adding module to our Nuxt application:

From now on you can register router module in your nuxt.config.js file:

As you probably noticed we want to utilize keepDefaultRouter option in order to preserve vanilla router implementation. Otherwise we will loose this nice Nuxt pages mapping with zero syntax sugar involved.

Router configuration

Our next step will be router.js file created in a root of our project structure:

Basically what this code does is checks whether page is located under sub-domain or root-domain directory and applies unwrapped routes accordingly.

Now it’s time to create some pages. As we noticed above, as long as we want to separate root domain and subdomain pages, we need to place them inside corresponding directories. I will assume you launch your app at localhost:3000 to demonstrate how paths will resolve:

You probably noticed a small caveat here: we don’t specify which subdomain is available. So any subdomain will result in pages/sub-domain/index.vue page rendering.

Now we can decide what to render in runtime by calling our backend services and checking for available data. If data doesn’t exist we can simply redirect to an error page.

Pages setup

It’s time to put some pages in our app and test it out. In case if you already had a structure of pages and willing to preserve it, simply move it inside pages/root-domain/ directory. Your index.vue page goes there as well. Launch our app and make sure all pages navigate normally.

In order to test our subdomains setup, we will put another index.vue page inside pages/sub-domain/ directory:

And when we open link we can finally see this:

Browser screenshot demonstrating subdomain page rendering
Browser screenshot demonstrating subdomain page rendering

By utilizing logic based on req context you can easily render content depending on the provided host link, or redirect to a 404 page if nothing was found.

Sample project

You can check sample project here:

Developer / entrepreneur