ROOT_URL can be problematic

The ROOT_URL environment variable must currently be set to a URL. Meteor will not accept a relative path like “/app”. Requiring a full URL with hostname (or IP address) included is problematic in some scenarios.

  1. One problem is with dual-homed systems where some client nodes can only reach the first network interface, and other client nodes can only reach the second network interface. When the client-side Meteor application tries to use a URL that was constructed from ROOT_URL, one of these clients will fail because the address that is part of ROOT_URL is not reachable from that client’s network.
  2. Environments where some users access the system with IP address, others with DNS name, or where both HTTP and HTTPS can be used to access the system. If ROOT_URL differs from what the user typed in the browser some fetch requests can fail because of cross-site scripting constraints.

Is there some way to specify a relative URL for Meteor to use, such that Meteor will use the client-side document root to complete the URLs for its own requests? Or some way to set a root_url variable dynamically with different values for different sessions?

1 Like

You’re confused. You should just setup your server properly so that you use vhosts. I have many meteor apps running on the same server no problem logging in or doing anything, same as using PHP and back in the day on Apache.

It’s very easy you just login to the server with ssh via the domain name as that just points to the A record which is the IP of your machine, the operating system is what determines the login authorization it has nothing to do with what stack you run.

The root url must be set so that the application knows what the domain name is for it to work you can’t use relative, doesnt matter what language you are using it’s part of the HTTPS protocol.

In Nginx it’s just this block in your conf

server {
        listen 80;
        listen [::]:80;

        root /path/to/your/app
        index index.html index.htm;


        location / {
                try_files $uri $uri/ =404;

You can read the manual here it’s very simple.

Thanks for trying to help. Unfortunately, you had misunderstood the question. This is not about virtual hosts.
As an example, consider a physical server that has two network interfaces, one with IP address on the black network, the other with IP address on the red network. These two networks are isolated from each other in the sense that a host on the black network cannot reach any address on the red network, and vice versa.
Why might anybody want to do this? The red network may carry sensitive traffic, which must only be accessible to hosts on the specially protected red network. Some services need to be accessible from both networks, for example a Meteor Web application.
This works fine for the most part, except when ROOT_URL comes into play, e.g., related to dynamic imports. When ROOT_URL is involved, the Web application asks the client to fetch from a specific IP address, and this can only work from one of the two disjoint networks.
Either we need the ability to use a relative path for ROOT_URL, allowing it to pick up the destination address from client context, essentially using the document root, or some way to dynamically change ROOT_URL based on client context.
I am aware of the possible workaround of running two separate applications, each listening on one interface only, setting ROOT_URL appropriate for that interface, but this is a resource-constrained system, and we cannot afford to consume twice the resources.

as your question is still missunderstood, here a solution that might help, at least for dynamic imports:

so setting

  "public": {
    "packages": {
      "dynamic-import": {
        "useLocationOrigin": true

this fixes lazy load on different hosts (e.g. hostname and ip adress).

you still can’t use relativ paths, but i think that would not be a solution to your problem.

Be aware that ROOT_URL might also be used in stuff like emails (for password reset links), but that should be easier to work around.

Another solution is to configure the DNS in your private network to resolve the public hostname to the internal ip adress


Finally got a chance to try this. With useLocationOrigin set to true the dynamic imports now work fine for our problem cases. So far I have not seen any unwanted side-effects. We don’t use password reset E-Mails because authentication is delegated to a backend.

This setting solves the problem for us, as long as there is no other use of ROOT-URL, which could bite us.

Thank you for the suggestion!