-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Astro v5: AlpineJS alpine:init event not working #12710
Comments
I'm surprised this even worked in v4, since the recommend way for Astro is to use the entrypoint option, see updated reproduction. I wonder is this is caused by this breaking change https://docs.astro.build/en/guides/upgrade-to/v5/#script-tags-are-rendered-directly-as-declared |
Has anyone found a possible solution? |
Moving <!doctype html>
<html lang="en-US">
<head>
...
<script>
document.addEventListener('alpine:init', () => {
console.log('test');
});
</script>
</head>
<body>
...
</body>
</html> If you want to add a
---
---
<!doctype html>
<html lang="en-US">
<head>
...
<slot name="in-head"></slot>
</head>
<body>
<slot></slot>
</body>
</html>
---
import Layout from '../layouts/Layout.astro';
---
<Layout title="Home">
<main>
<h1>Home</h1>
<div x-data="counter">
<span x-text="value"></span>
<button @click="increment">Increment</button>
</div>
</main>
<Fragment slot="in-head">
<script>
import Alpine from 'alpinejs';
Alpine.data('counter', () => ({
value: 0,
increment() {
this.value++;
}
}));
</script>
</Fragment>
</Layout> However, this workaround doesn't work for scripts in components. I think it would be great if |
By the way, does it work if you add the |
Yes, using ---
import Layout from '@/layouts/Layout.astro';
---
<Layout title="Home">
<main>
<h1>Home</h1>
<div x-data="counter">
<span x-text="value"></span>
<button @click="increment">Increment</button>
</div>
</main>
</Layout>
<script is:inline>
document.addEventListener('alpine:init', () => {
Alpine.data('counter', () => ({
value: 0,
increment() {
this.value++;
}
}));
});
</script> |
I discussed it with other core maintainers and we think you were depending on implicit, unintentional behavior, and
Hope that helps |
When using AlpineJS with an entry point (as recommended) the issue exists in v5 and works in v4. As far as I can tell, the real issue is that The beauty of AstroJS + AlpineJS is that Alpine components that may be used on multiple times within a page or on different pages are bundled into a shared Javascript file. If you have an Alpine component (e.g. an article card) that is render 20 times on a page, the If all scripts must be inline, existing AstroJS v4 sites really cannot be upgraded to v5 without significant issues, unless they were built sub-optimally (e.g. all scripts where Here is another example illustrating the issue. Note that this example works in v4, but does not work in v5. https://stackblitz.com/edit/withastro-astro-xaotss6x?file=src%2Fpages%2Findex.astro&title=Astro%20Starter%20Kit:%20Minimal |
I think I found a workaround! Me just being a tinkerer and the 'depending on implicit, unintentional behavior' comment makes me wonder how solid it is. If someone could explain why this is a bad idea, I'd be happy to hear it. Edit: I do not recommend this! It only works when a single Alpine component is on the page, as otherwise Alpine.start() is called multiple times. I've removed <!-- Do not copy this code before reading my edit above! -->
<script>
import Alpine from "alpinejs";
import myUtility from "@src/utilities/myUtility";
import type { Locale } from "@i18n/i18n";
type Props = {
value: string | number;
locale: Locale;
};
document.addEventListener("alpine:init", () => {
Alpine.data("myComponent", (props: Props) => ({
// Add component logic here ...
}));
});
window.Alpine = Alpine;
Alpine.start();
</script> |
That sounds fair, I'll reopen and bring it up again
Fwiw you can have type checked inline scripts by using |
Turns out, my silly workaround above isn't very useful if you have more than one Alpine component on a page. I've fallen back to my Astro <4 workaround:
<script>
import Alpine from "alpinejs";
window.setTimeout(() => {
window.Alpine = Alpine;
Alpine.start();
}, 1);
</script> |
Thank you for reopening the ticket. I'm not highly familiar with the inner workings of Astro under the hood, but I did some investigation. It appears that the For example the following component (Welcome.astro) script:
On build, this script is compiled into the HTML as a module:
This may be considered intentional behavior, however, it is not how Astro V4 handled scripts tags in components from my experience. |
I think injecting the script at the end of the page could help, as it would run after all other scripts are initialized (I may be wrong). @bluwy do we have a way to do that? Right now the integration uses |
According to the Astro documentation (https://docs.astro.build/en/reference/directives-reference/#isinline):
This statement does not appear to be true in Astro V5 regardless of using the AlpineJS integration. <script>
console.log("hello, world!");
</script> The above script will be rendered as an inline script module: <script type="module">console.log("hello, world!");</script> With AlpineJS integrated, if I manually remove // Works
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js"></script>
<script>
document.addEventListener('alpine:init', () => {
alert("alpine:init");
});
</script> // Works
<script type="module">
document.addEventListener('alpine:init', () => {
alert("alpine:init");
});
</script>
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js"></script> // Does not work
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js"></script>
<script type="module">
document.addEventListener('alpine:init', () => {
alert("alpine:init");
});
</script> In AstroV4 + AlpineJS, it appears there are two compiled javascript files for each page: hoisted.{hash}.js and page.{hash}.js. Both are included as modules; hoisted.{hash}.js runs before page.{hash}.js. The very last line of page.js is starting Alpine JS. In AstroV5 + AlpineJS it appears that the hoisted.{hash}.js file is no longer used in favor of just page.{hash}.js. The last line of page.{hash}.js is starting AlpineJS. Optimally, AlpineJS integration should work for scripts that are bundled or inline. For that to be the case, it seems that |
Btw it happens here in the integration https://github.com/withastro/astro/blob/main/packages/integrations/alpinejs/src/index.ts#L95-L102 |
@florian-lefebvre That is correct. However, from what I can see in the Git history, that integration has not changed from Astro 4 to Astro 5. I appreciate the fact that I am one developer using Astro with AlpineJS and Astro is used by many developers with other integrations. However, from my perspective, the issue is that Astro is not properly bundling scripts as the documentation states (https://docs.astro.build/en/reference/directives-reference/#isinline).
Since the compiled script with AlpineJS is included as a |
@jasonlav this is not as easy, we've removed the old behavior for good reasons (I can't explain because I was not involved in this process). Anyways, thanks for all the details. At this point, I feel like we have all the information we need to think about it, we just need to take the time. Do not expect a quick fix because it doesn't sound trivial |
I understand. Correction: I previously said if a page had multiple instances of the same component and that component had an |
Astro Info
If this issue only occurs in one browser, which browser is a problem?
No response
Describe the Bug
The event of AlpineJS
alpine:init
is not working anymore in Astro 5.It works in astro 4.16.17, but not in astro 5.0.4
What's the expected result?
document.addEventListener('alpine:init', () => {
// this event should be triggered
});
The AlpineJS documentation shows that it should work : https://alpinejs.dev/globals/alpine-data
Link to Minimal Reproducible Example
https://stackblitz.com/edit/github-sscqvr22?file=src%2Fpages%2Findex.astro
Participation
The text was updated successfully, but these errors were encountered: