#Get server origin (Astro.url.origin)

12 messages · Page 1 of 1 (latest)

lunar fog
#

Hi,

I've spent a lot of time searching through the documentation, GitHub issues, and Discord messages but couldn't find a single working way to get the server's address (which defaults to "http://localhost:4321"). I haven't had success with Vite/Astro environment variables or any other methods. All I want is to:

  1. Get the value of the origin, globally, outside of Astro components.
  2. Do this without explicitly declaring the address in the configuration.
vagrant vapor
#

Hey! I'm not sure this is really possible tbh. Servers don't typically know where they're hosted, they usually never need to know. It's up to the developer to host them and know where to point dns records or requests.

Typically you'll host a server somewhere, and you'll know the location or IP address. You can load that as an environment variable wherever you need it later on

lunar fog
#

@vagrant vapor But why not? What harm could it have to just "dump" all server parameters to a read-only object? e.g. Vite has 'server.host' and 'server.port'.
Regarding "knowing the address", I want to take advantage of dynamic adresses to be able to spin up multiple servers or just work with multiple projects at the same time and never think of the addresses in the process, as it's just an extra step.

#

...And not having access—or any possible way to access—such basic information made the entire task nearly impossible to get right. I either have to settle for hardcoded values, which is far from ideal, or find out if there’s another way to obtain the sizes (which only delays the issue, as this isn’t the first time I’ve needed the origin).

vagrant vapor
#

So Astro does provide a global of Astro.url which is a readonly property of the request location. It also has Astro.site , but you'll have had to set that in your Astro config for it to pick it up.

Afaik, this isn't a problem of it "doing harm" or not being accessible, it's that the server fundamentally does not contain that information. All a server knows is what port to listen on, and because you can access your server through many different ways (localhost, 127.0.0.1, 0.0.0.0, or any other custom host name you've set up on your machine), the server has literally no idea which one you'll be accessing it on. It has no outside knowledge of www IP or hostname. It'd be like trying to call your own mobile phone, but you don't know what your number is - it may as well be impossible.

It's also worth noting that the Vite server runs in development too, your live server will be out of Vite-land.

As soon as you're looking at dynamic addresses, hosts or domains or anything, your solutions complexity is going to increase massively. I'm sure there'll be some clever way of doing through through docker, but I'm not exactly sure what it'll be. But it will involve setting an environment variable of the machine's address.

So just to double check, you have an Astro server hosted at say https://[dynamic-name].mydomain.com , for example, and you want the server to be able to request remote images from itself, and have knowledge of that url you're pointing at it?

lunar fog
#

@vagrant vapor Thanks for your response.

I understand your explanation about the server not inherently knowing its address. My point wasn't that it should magically know every possible way to access it. I just meant that at least, there is a known port being used. It seems reasonable that this information should be globally available to the application. (I'm referring to the Local http://localhost:4321/ response that appears after running npm run astro dev, regardless of additional network addresses.)

My use case is pretty straightforward. I'm just talking about local development, no SSR or complex deployments. When I build the site locally, I just need a way to programmatically determine the port outside of Astro components (like 4321 in the typical http://localhost:4321 example) so I can construct the full URL. Something like inferRemoteSize("http://localhost:" + port + "/" + imgPathname) would be perfect. This avoids hardcoding the port and makes it more flexible for different projects or when ports change. I'm not dealing with dynamic hostnames at this stage, just the dynamic port assignment of the dev server.

lunar fog
#

Tried writing a Vite plugin:

import type { PluginOption } from "vite";

let localOrigin: string | null = null;

export function getLocalOrigin() {
  if (localOrigin) return localOrigin;
  throw new Error("Found attempt to access local origin before it's set.");
}

export const vitePortReaderPlugin: PluginOption = {
  name: "port-reader",
  configureServer(server) {
    server.httpServer?.once("listening", () => {
      const address = server.httpServer?.address();
      if (address && typeof address === "object") {
        localOrigin = `http://127.0.0.1:${address.port}`;
      }
    });
  },
};

But no success. It hits the read exception. I'm guessing it's because the code reaches getLocalOrigin() earlier than when the localOrigin is set, or the variable is being cleared for whatever reason.

lunar fog
#

Bad news: Even hardcoding an IP doesn't seem to work! It works properly while a dev server is running, but with npm run build, fetch fails. This is officially a dead end. Are there any solutions for this?

lunar fog
#

Many months later and I keep finding another use-case which needs this particular option. Am I really the only one here?

modest river
#

It should be possible to get the port in configureServer, and pass it to a virtual module

#

You can't export things like that in the config file, the actual config is running in a different context