New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accessing the current domain name client side and in SSR, consistently? #2378

Closed
irrg opened this Issue Dec 12, 2017 · 15 comments

Comments

Projects
None yet
8 participants
@irrg
Copy link

irrg commented Dec 12, 2017

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—I've gone through the docs and searched all open and closed issues (but it's possible I didn't use the right search terms).

This question is available on Nuxt.js community (#c2069)
@christophwolff

This comment has been minimized.

Copy link

christophwolff commented Dec 12, 2017

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.

@irrg

This comment has been minimized.

Copy link
Author

irrg commented Dec 12, 2017

That's a bummer. Since every account gets a subdomain, there's no way to keep a running list in a variable.

@christophwolff

This comment has been minimized.

Copy link

christophwolff commented Dec 12, 2017

try to access it in the nuxtServerInit Action:
https://nuxtjs.org/guide/vuex-store#the-nuxtserverinit-action
req.headers.host

@christophwolff

This comment has been minimized.

Copy link

christophwolff commented Dec 12, 2017

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

@irrg

This comment has been minimized.

Copy link
Author

irrg commented Dec 13, 2017

You're a lifesaver, @christophwolff. Trying the former first, because I already started, will report back on the latter.

@irrg

This comment has been minimized.

Copy link
Author

irrg commented Dec 13, 2017

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!

@clarkdo clarkdo closed this Dec 13, 2017

@christophwolff

This comment has been minimized.

Copy link

christophwolff commented Dec 13, 2017

@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...
#1695 (comment)

@sudhir600

This comment has been minimized.

Copy link

sudhir600 commented Apr 24, 2018

@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)

@JeremyGranger

This comment has been minimized.

Copy link

JeremyGranger commented Sep 22, 2018

@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?

@irrg

This comment has been minimized.

Copy link
Author

irrg commented Sep 23, 2018

@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' })
      }
    },
@davegriffin

This comment has been minimized.

Copy link

davegriffin commented Oct 8, 2018

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.

@samir-araujo

This comment has been minimized.

Copy link

samir-araujo commented Oct 31, 2018

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

@Globerada

This comment has been minimized.

Copy link

Globerada commented Nov 2, 2018

@samir-araujo , shouldn't be req.headers['real-host'] !== undefined ??

@samir-araujo

This comment has been minimized.

Copy link

samir-araujo commented Nov 16, 2018

@samir-araujo , shouldn't be req.headers['real-host'] !== undefined ??

Whoops! Thanks! I have updated my comment

@lock

This comment has been minimized.

Copy link

lock bot commented Dec 16, 2018

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.

@lock lock bot locked as resolved and limited conversation to collaborators Dec 16, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.