withastro / astro

The web framework for content-driven websites. ⭐️ Star to support our work!
https://astro.build
Other
46.95k stars 2.49k forks source link

Vite server.origin does not seem to work #11891

Open aminevg opened 2 months ago

aminevg commented 2 months ago

Astro Info

Astro                    v4.15.1
Node                     v18.20.3
System                   Linux (x64)
Package Manager          unknown
Output                   static
Adapter                  none
Integrations             none

If this issue only occurs in one browser, which browser is a problem?

No response

Describe the Bug

Vite has a server.origin option that defines the origin of any asset URLs that are generated during development. This is usually used when integrating a front-end framework with a back-end solution (see Backend Integration). This would pair well with the experimental Container API to allow for embedding Astro components into other languages. However, the server.origin option does not seem to work in the current state.

Setting Astro's configuration to the following should add the origin http://example.com to all generated asset URLs:

import { defineConfig } from 'astro/config';

// https://astro.build/config
export default defineConfig({
  vite: {
      server: {
          origin: 'http://example.com'
      }
  },
});

So the following script tag:

<script type="module" src="/src/pages/index.astro?astro&type=script&index=0&lang.ts"></script>

should change to something like this:

<script type="module" src="http://example.com/src/pages/index.astro?astro&type=script&index=0&lang.ts"></script>

But this is not the case currently, and the server.origin option seems to have no effect on asset URL generation.

The minimal reproduction includes three typical(?) asset generation scenarios:

I would be open to submitting a PR for this, but I am not sure where the issue might be, even though I have looked into the Astro source code. If someone could point me in the right direction, I could try to implement a fix for this!

What's the expected result?

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-9kqvn7

Participation

ascorbic commented 2 months ago

For assets you can use the build.assetsPrefix option. I'm not sure of the use case for adding an origin domain during dev.

aminevg commented 2 months ago

@ascorbic Thanks for the suggestion! build.assetsPrefix would be a great choice for serving production builds. (astro build or astro preview) A use case I had in mind for the dev story is the integration of the Container API with a backend framework. I'll take Laravel as a example here, since that's the integration I'm trying to develop for. (Let me know if there is another way of solving this!)

Let's say you have a Laravel dev server running on port 8080, and a Laravel Blade template that includes an Astro component:

<html>
  <head>
    <title>Laravel Blade Example</title>
  </head>
  <body>
    <div id="container">
      @astro("Button") <!-- A directive that means: Include the "Button" Astro component -->
    </div>
  </body>
</html>

The "Button" Astro component could look like this:

<!-- This component is located at src/components/Button.astro -->
<button id="buttonToClick">Click me!</button>

<script>
document.getElementById('buttonToClick')
  .addEventListener("click", () => alert("You clicked the button! Good job!"));
</script>

If you were to spin up a dev server on port 5173 (using astro dev or the Javascript API), rendered the above component, and passed it back to the Laravel Blade template, you would end up with the following:

    <div id="container">
      <button id="buttonToClick">Click me!</button>

      <!-- The script tag would render here if experimental.directRenderScript is turned on, or inside the head tag otherwise -->
      <script type="module" src="/src/components/Button.astro?astro&type=script&index=0&lang.ts"></script>
    </div>

We rendered the component in dev mode, so no problem, right? Except if you're accessing the local site via http://localhost:8080 (because you're using the Laravel dev server), this script path:

"/src/components/Button.astro?astro&type=script&index=0&lang.ts"

would be resolved by the browser as:

// Will try to get the script content from the Laravel dev server
"http://localhost:8080/src/components/Button.astro?astro&type=script&index=0&lang.ts"

But we actually want the Vite/Astro dev server to resolve it!

// Will try to get the script content from the Vite/Astro dev server
"http://localhost:5173/src/components/Button.astro?astro&type=script&index=0&lang.ts"

This would not be a problem if the Astro server? Vite plugins? respected the server.origin option, but this does not seem to be the case right now.