This article covers subdomains routing implementation using Nuxt.js and @nuxtjs/router.
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:
- Add router npm package.
- Create custom logic inside route.js file.
- Create subdirectories for root and subdomain pages.
- 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:
yarn add --dev @email@example.com
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.
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:
pages/root-domain/index.vue // => localhost:3000
pages/root-domain/hello.vue // => localhost:3000/hello// 'anything' below is a wildcard which can contain even multiple levels of subdomains, such as foo.bar.localhost:3000 etc...pages/sub-domain/index.vue // => anything.localhost:3000
pages/sub-domain/world.vue // => anything.localhost:3000/worldpages/info.vue // will be available on all domains
You probably noticed a small caveat here: we don’t specify which subdomain is available. So any subdomain will result in
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.
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
And when we open http://hello.world.localhost:3000 link we can finally see this:
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.
You can check sample project here: