Hi there. I've just started a new app that runs with a wildcard subdomain. So, I'm going to be rendering foo.com
, bar.foo.com
, and many many other subdomains pointing to the _same_ nuxt.js server instance.
I'm looking for a way for my most root-y of pages
, index.vue
, to be able to distinguish if it's running on the main domain foo.com
, or if it's on one of our zillions of subdomains.
I understand that created
is the best lifecycle event to grab this info, but obviously window.location
only exists on the client side. I cannot, for the life of me, figure out how I might distinguish what domain name was used when the page is rendered on the Server Side.
I've poked around at process
, but I'm not sure what the right place is.
So, basically:
created () {
if (process.browser) {
console.log(window.location)
} else {
console.log('*****')
// console.log(something_something_something)
console.log('*****')
}
}
and this is where I'm stuck. Help most welcome鈥擨've gone through the docs and searched all open and closed issues (but it's possible I didn't use the right search terms).
you could use env variables with the sub domains in nuxt.config.js.
https://nuxtjs.org/api/configuration-env/
In my knowledge the node.js server isnt aware of the domain or subdomain he is running on.
That's a bummer. Since every account gets a subdomain, there's no way to keep a running list in a variable.
try to access it in the nuxtServerInit Action:
https://nuxtjs.org/guide/vuex-store#the-nuxtserverinit-action
req.headers.host
Another method in Page
asyncData ({req}) {
console.log(req.headers)
},
But i think you need the axios module to inject the request. https://github.com/nuxt-community/axios-module
You're a lifesaver, @christophwolff. Trying the former first, because I already started, will report back on the latter.
req.headers.host
seems to work solidly even without the axios module (but I'm using axios anyway, so I'll probably roll with the official module) although I'm gonna kick the tires a bit on if this consistently works. But:
let host = req ? req.headers.host : window.location.host.split(':')[0]
in asyncData
seems to be the key! thanks @christophwolff!
@irrg fyi: i abandoned the axios module and wrote a little implementation on my own. i had a serious memory leak with it. dont know if this will effect you...
https://github.com/nuxt/nuxt.js/issues/1695#issuecomment-345444513
@irrg your solution is worked perfectly but how to get protocol. As i am running my local setup on http but at UAT and production with https:// so I want to get this dynamically on middleware (SSR)
@irrg Hi Rob, I know this is an old post, but I'm currently trying to create some logic in my Nuxt app where I choose a logo based on what subdomain is used to access the app. I can't understand how to see this information, even with the posts above. Not quite sure where in code to place your solution. Do you mind giving me some advice here?
@JeremyGranger Here's a bit from my notes, I haven't tested the code (project got canceled) but it should be a good start.
First I have a helper function called getDomainDetails
function getDomainDetails (req) {
let nonSubdomainHosts = ['host1.com', 'local.host1.com']
let host = (req
? req.headers.host
: window.location.host)
.toLowerCase()
.replace(/www./g, '')
let handle = null
let port = null
if (host.indexOf(':') > 0) {
[host, port] = host.split(':')
}
const isSubdomain = (nonSubdomainHosts.indexOf(host) === -1)
if (isSubdomain) {
const hostSplit = host.split('.')
[handle, host] = [hostSplit.shift, hostSplit.join('.')]
}
return {
host: host + (port ? ':' + port : ''),
isSubdomain
handle
}
}
Then I was using it in the context of asyncData like this:
async asyncData ({ params, req, store, query, error }) {
try {
/* this is where you pass req to the helper and get what you need, in my case, host and handle */
const { host, handle } = getDomainDetails(req)
const topicId = params.slug.split('-')[0]
const page = query.page ? query.page : 1
let topic = await axios.get(`topics/${topicId}?handle_id=${handle}&page=${page}`)
return {
handle,
page,
host,
baseURL: '/' + params.slug,
topic: topic.data
}
} catch (e) {
error({ statusCode: 404, message: 'Topic not found' })
}
},
I have no idea if this will ultimately work (as I'm still early in our prototyping stage), but I used server middleware to do some pre-processing on the requests (mapping subdomains to internal theme/skin information) and placed the information in the req.session storage.
I know its a century old issue, but I have stumbled upon this thread so many times when searching for exactly the same problem, that I wanted to share what I did to solve my problem.
As @irrg, we are building an saas with SSR, so we do not know before hand all the possible subdomains, so req.headers.host returns "localhost:$port" (we use NGINX as a reverse proxy) instead of "subdomain.domain.com".
Since NGINX knows the real host, we added a header with the host using NGINX before handing the request to Nuxt JS.
The NGINX block looks something like this:
location /pt-BR {
proxy_set_header Real-Host $http_host;
proxy_pass http://localhost:3000;
}
And on Nuxt JS we have this:
if (req.headers['real-host'] !== undefined) {
let realHost = `https://${req.headers['real-host']}`;
...
}
Hope it helps someone else
@samir-araujo , shouldn't be req.headers['real-host'] !== undefined ??
@samir-araujo , shouldn't be req.headers['real-host'] !== undefined ??
Whoops! Thanks! I have updated my comment
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
@irrg your solution is worked perfectly but how to get protocol. As i am running my local setup on http but at UAT and production with https:// so I want to get this dynamically on middleware (SSR)