Comments (13)
Here is solution using @nuxt/router-module
All pages from folder 'pages/root-domain' will be available on 'example.com'
All pages from folder 'pages/sub-domain' will be available on 'foo-bar.example.com'
All other pages will be available on any domain
// router.js
import Router from 'vue-router'
export function createRouter(ssrContext, createDefaultRouter, routerOptions) {
const options = routerOptions || createDefaultRouter(ssrContext).options
let routesDirectory = null
if (process.server && ssrContext && ssrContext.nuxt && ssrContext.req) {
const req = ssrContext.req
const domainLevel = (req.headers.host.match(/\./g) || []).length + 1
// Get routes directory by hostname
routesDirectory = domainLevel > 2 ? 'sub-domain' : 'root-domain'
// Save to the object that will be sent to the client as inline-script
ssrContext.nuxt.routesDirectory = routesDirectory
}
if (process.client) {
// Get what we saved on SSR
if (window.__NUXT__ && window.__NUXT__.routesDirectory) {
routesDirectory = window.__NUXT__.routesDirectory
}
}
function isUnderDirectory(route, directory) {
const path = route.path
return path === '/' + directory || path.startsWith('/' + directory + '/')
}
let newRoutes = options.routes
if (routesDirectory) {
newRoutes = options.routes
.filter((route) => {
// remove routes from other directories
const toRemove =
routesDirectory === 'sub-domain'
? 'root-domain'
: 'sub-domain'
return !isUnderDirectory(route, toRemove)
})
.map((route) => {
// remove directory from path and name
if (isUnderDirectory(route, routesDirectory)) {
return {
...route,
path: route.path.substr(routesDirectory.length + 1) || '/',
name: route.name.substr(routesDirectory.length + 1) || 'index'
}
}
return route
})
}
return new Router({
...options,
routes: newRoutes
})
}
from router-module.
Hello @Aperrix, I've created a module to handle multiple subdomains with nuxtJS, inspired by the answer of @verstoff but not limiting to just one subdomain, you can add any number of domains, please have a look k-domains thanks @verstoff for the initial idea.
from router-module.
The problem is your going to solve the problem only with nuxt but what you actually need is reverse proxy.
you can use nginx for instead.
from router-module.
Hello, I've followed this guide and all seem to work perfectly on localhost. However when I deploy using nuxt-generate
it seems that it shows always the root-domain
and never the sub-domain
this is probably because they get generated without subdomain and then this never runs again. Is there a way to have something like this which works with nuxt generate? Any workaround I can try?
from router-module.
Here is solution using @nuxt/router-module
All pages from folder 'pages/root-domain' will be available on 'example.com' All pages from folder 'pages/sub-domain' will be available on 'foo-bar.example.com' All other pages will be available on any domain
// router.js import Router from 'vue-router' export function createRouter(ssrContext, createDefaultRouter, routerOptions) { const options = routerOptions || createDefaultRouter(ssrContext).options let routesDirectory = null if (process.server && ssrContext && ssrContext.nuxt && ssrContext.req) { const req = ssrContext.req const domainLevel = (req.headers.host.match(/\./g) || []).length + 1 // Get routes directory by hostname routesDirectory = domainLevel > 2 ? 'sub-domain' : 'root-domain' // Save to the object that will be sent to the client as inline-script ssrContext.nuxt.routesDirectory = routesDirectory } if (process.client) { // Get what we saved on SSR if (window.__NUXT__ && window.__NUXT__.routesDirectory) { routesDirectory = window.__NUXT__.routesDirectory } } function isUnderDirectory(route, directory) { const path = route.path return path === '/' + directory || path.startsWith('/' + directory + '/') } let newRoutes = options.routes if (routesDirectory) { newRoutes = options.routes .filter((route) => { // remove routes from other directories const toRemove = routesDirectory === 'sub-domain' ? 'root-domain' : 'sub-domain' return !isUnderDirectory(route, toRemove) }) .map((route) => { // remove directory from path and name if (isUnderDirectory(route, routesDirectory)) { return { ...route, path: route.path.substr(routesDirectory.length + 1) || '/', name: route.name.substr(routesDirectory.length + 1) || 'index' } } return route }) } return new Router({ ...options, routes: newRoutes }) }
this is not working when using nuxt-i18n module.
from router-module.
@Aperrix can you share your code for subdomain nuxt router.
from router-module.
@verstoff is there a way how to make your code work in a more general way.
Let's say I have more domains/subdomains that I want to map on more directories.
page/admin.domain.com > will show only on the subdomain admin.domain.com
page/example.com > will show only on the domain example.com
page/anotherpage.com > will show only on the domain anotherpage.com
page/subdomain.example.com > will show only on the subdomain.example.com
Therefore I can have multiple domains and subdomains pointing on one server with one NuxtJS SSR app.
THX
from router-module.
There is two steps:
- Determine which directory is needed for the requested domain:
routesDirectory = req.headers.host
suitable for your purposes - Exclude all routes that matches your domain directories (except current one - routesDirectory) from routes list.
For your purposes change filter method to something like this:
const domains = [
'admin.domain.com', 'example.com', 'anotherpage.com', 'subdomain.example.com'
]
...
newRoutes = options.routes.filter((route) => {
if (isUnderDirectory(route, routesDirectory)) {
return true
}
// remove routes from other domain-directories
return !domains.find(domain => isUnderDirectory(route, domain))
})
Or you can define some prefix for domain-directories and filter routes by it.
from router-module.
This is almost exactly what I need for my app. I'm trying to replicate the method that heroku uses on their site.
I am aiming for 2 domains - example.com and dashboard.example.com. The idea is that if an unauthenticated user goes to dashboard.example.com, they are forced to log in first - at example.com/login - then they're redirected to the main dashboard page.
Using @verstoff's solution above, I managed to get the subdomains working (although I needed to change the domainLevel check to 1, from 2) but if I put the auth middleware on the dashboard page (to force a user login), I can't get it to go to example.com/login.
- If I put the login.vue page in the root of the pages directory (pages/login.vue), the login page is dashboard.example.com/login. It looks like Heroku does this - then that page redirects to the real login page (which is at id.heroku.com) but how would I go about that, without just hardcoding the url?
- If I put the login.vue page in the root-domain (pages/root-domain/login.vue), the login page is not found.
Any ideas?
from router-module.
In order not to hardcode, you can get domain of the authorization page using string methods or regular expressions, knowing the required domain level and req.headers.host
. Then save the result somewhere, for example, in ssrContext.nuxt.loginURL (like in my answer), which is available both on the server and on the client (via a global variable). In the middleware, get this variable and redirect to the resulting domain instead of current.
Make sure the redirection happens through 30x code on the server and through location on the client (with a page reload and not just a Vue Router route change).
from router-module.
Thanks @verstoff - I used the runtime config to do that in the end, so thanks for that!
from router-module.
Here is solution using @nuxt/router-module
All pages from folder 'pages/root-domain' will be available on 'example.com'
All pages from folder 'pages/sub-domain' will be available on 'foo-bar.example.com'
All other pages will be available on any domain// router.js import Router from 'vue-router' export function createRouter(ssrContext, createDefaultRouter, routerOptions) { const options = routerOptions || createDefaultRouter(ssrContext).options let routesDirectory = null if (process.server && ssrContext && ssrContext.nuxt && ssrContext.req) { const req = ssrContext.req const domainLevel = (req.headers.host.match(/\./g) || []).length + 1 // Get routes directory by hostname routesDirectory = domainLevel > 2 ? 'sub-domain' : 'root-domain' // Save to the object that will be sent to the client as inline-script ssrContext.nuxt.routesDirectory = routesDirectory } if (process.client) { // Get what we saved on SSR if (window.__NUXT__ && window.__NUXT__.routesDirectory) { routesDirectory = window.__NUXT__.routesDirectory } } function isUnderDirectory(route, directory) { const path = route.path return path === '/' + directory || path.startsWith('/' + directory + '/') } let newRoutes = options.routes if (routesDirectory) { newRoutes = options.routes .filter((route) => { // remove routes from other directories const toRemove = routesDirectory === 'sub-domain' ? 'root-domain' : 'sub-domain' return !isUnderDirectory(route, toRemove) }) .map((route) => { // remove directory from path and name if (isUnderDirectory(route, routesDirectory)) { return { ...route, path: route.path.substr(routesDirectory.length + 1) || '/', name: route.name.substr(routesDirectory.length + 1) || 'index' } } return route }) } return new Router({ ...options, routes: newRoutes }) }
I added this in my Nuxt directory and it doesn't do anything for me.
Is there anything else needed for this to work?
from router-module.
createDefaultRouter
I am getting createDefaultRouter is not a function error, any idea why? is this code need to be updated?
from router-module.
Related Issues (20)
- base route is appended to url on page referesh HOT 1
- next() function is not working well HOT 1
- children in route.js don't work HOT 2
- Custom router in .nuxt folder HOT 2
- does it support nuxt3 with vue3 HOT 3
- Vue router 4 support HOT 6
- Release HOT 1
- Cannot start nuxt: Cannot find module 'nuxt/lib/app/router' in nuxt3 HOT 5
- Readme "If you are using Nuxt < 2.16.0, the parameter store is not available" HOT 2
- the css load order changes after using @nuxtjs/router
- Cannot extend routes from a module
- Code splitting not working with router.js HOT 3
- `Cannot read properties of undefined (reading 'options')` on add @nuxtjs/router to Nuxt 3 project HOT 1
- Docs: Missing correct docs about the `store` parameter.
- Can I access to the routes within another module?
- Anchor link dont work on yarn generate
- Is this module compatible with SSG build?
- Nuxt 3 Support HOT 1
- Nuxt content not generate or parse to custom router
- Hydratation error with SSG HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from router-module.