Wildcard subdomain info sharing between node server and Nuxt/Vue client
Asked Answered
C

1

6

We are building a multi_tenant solution with NodeJS/Express for the back end and VueJS/Nuxt for the front-end. Each tenant will get their own subdomain like x.mysite.com, y.mysite.com, etc.

How can we make both our back end and front-end read the subdomain name and share with each other?

I have some understanding that in the Vue client, we can read suvdomain using window.location. But I think that's too late. Is there a better way? And what about the node /express setup? How do we get the suvidhaon info there?

Note that Node/Express server is primarily an API to interface with database and for authentication.

Any help or insight to put us on the right path is appreciated.

Cordi answered 3/9, 2018 at 11:21 Comment(0)
T
1

I'm doing something similar in my app. My solution looks something like this...

Front End: In router.vue, I check the subdomain to see what routes to return using window.location.host. There is 3 options

  1. no subdomain loads the original routes (mysite.com)
  2. portal subdomain loads the portal routes (portal.mysite.com)
  3. any other subdomain loads the routes for the custom client subdomain, which can be anything and is dynamic

My routes for situation #3 looks like this:

import HostedSiteHomePage from 'pages/hostedsite/hosted-site-home'
export const hostedSiteRoutes = [
    { path: '*', component: HostedSiteHomePage }
]

The asterisk means that any unmatched route will fallback to it.

In your fallback page (or any page), you will want this (beforeMount is the important part here):

beforeMount: function () {
    var host = window.location.host
    this.subdomain = host.split('.')[0]
    if (this.subdomain === 'www') subdomain = host.split('.')[1]

    this.fetchSiteContent()
},
methods: {
    fetchSiteContent() {
        if (!this.subdomain || this.subdomain === 'www') {
            this.siteContentLoaded = true
            this.errorLoadingSite = true
            return
        }

        // send subdomain to the server and get back configuration object
        http.get('/Site/LoadSite', { params: { site: this.subdomain } }).then((result) => {

            if (result && result.data && result.data.success == true) {
                this.siteContent = result.data.content
            } else {
                this.errorLoadingSite = true
            }

            this.siteContentLoaded = true

        }).catch((err) => {
            console.log("Error loading " + this.subdomain + "'s site", err)
            this.errorLoadingSite = true
            this.siteContentLoaded = false
        })
    },
}

I store a configuration object in json in the database for the subdomain, and return that to the client side for a matching subdomain then update the site to match the information/options in the config object.

Here is my router.vue

These domain names are supported:

mysite.com (loads main/home routes)
portal.mysite.com (loads routes specific to the portal)
x.mysite.com (loads routes that support dynamic subdomain, fetches config from server)
y.mysite.com (loads routes that support dynamic subdomain, fetches config from server)

localhost:5000 (loads main/home routes)
portal.localhost:5000 (loads routes specific to the portal)
x.localhost:5000 (loads routes that support dynamic subdomain, fetches config from server)
y.localhost:5000 (loads routes that support dynamic subdomain, fetches config from server)
import Vue from 'vue'
import VueRouter from 'vue-router'

// 3 different routes objects in routes.vue
import { portalRoutes, homeRoutes, hostedSiteRoutes } from './routes'

Vue.use(VueRouter);

function getRoutes() {
    let routes;
    var host = window.location.host
    var subdomain = host.split('.')[0]
    if (subdomain === 'www') subdomain = host.split('.')[1]
    console.log("Subdomain: ", subdomain)

    // check for localhost to work in dev environment
    // another viable alternative is to override /etc/hosts
    if (subdomain === 'mysite' || subdomain.includes('localhost')) {
        routes = homeRoutes
    } else if (subdomain === 'portal') {
        routes = portalRoutes
    } else {
        routes = hostedSiteRoutes
    }
    return routes;
}

let router = new VueRouter({
    mode: 'history',
    routes: getRoutes()
})

export default router

As you can see I have 3 different set of routes, one of which is a set of routes that supports dynamic subdomains. I send a GET request to the server once i load the dynamic subdomain page and fetch a configuration object that tells the front end what that site should look like.

Toolis answered 12/4, 2022 at 16:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.