#CSS not loading in a script src
20 messages · Page 1 of 1 (latest)
Hi @weak pewter. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
When using Astro’s <ClientRouter /> for view transitions, client-side navigation replaces only the page content without a full browser refresh. This can affect how external scripts and their associated CSS are loaded.
If you include a script like:
<script is:inline src="<https://xxx/libraries/xxx.js"></script>>
and that script is responsible for injecting or loading CSS dynamically, the CSS may not be re-applied after client-side navigation. This is because, during view transitions, scripts with is:inline and external sources are not automatically re-executed when navigating between pages—unlike a full page reload, which would re-run all scripts and re-apply styles.
Why does this happen?
- With
<ClientRouter />, only new scripts that appear on the new page are executed. If the script tag exists on both the old and new page, it is not re-executed after navigation. - Inline scripts (including those with
is:inlineand asrc) may not re-run unless you explicitly tell Astro to do so, or unless you use lifecycle events to trigger the necessary logic after navigation. - If your external JS is responsible for loading CSS, and it doesn't run again after navigation, the CSS will not be applied on the new page [Script behavior with view transitions].
How to fix:
-
Use Lifecycle Events:
Wrap your script logic in a listener for theastro:page-loadorastro:after-swapevent, so it runs after every client-side navigation. For example:document.addEventListener("astro:page-load", () => { // Your logic to load CSS or re-initialize the library }); -
Force Script Re-execution:
If you want an inline script to re-run after every transition, add thedata-astro-rerunattribute:
<script is:inline data-astro-rerun src="<https://xxx/libraries/xxx.js"></script>>
This will ensure the script is executed on every client-side navigation [Script behavior with view transitions].
Summary:
With <ClientRouter />, scripts (and any CSS they load) may not re-run or re-apply after navigation unless you use lifecycle events or the data-astro-rerun attribute. This is different from a full page reload, where everything is re-executed. Adjust your script loading strategy as described above to ensure your CSS is applied correctly after client-side navigation.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@weak pewter Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@long bronze , can you explain in more detail the first solution
Let me check the knowledge base for you again. One moment! :books:
Certainly! The first solution involves using Astro’s lifecycle events to ensure your script logic (such as loading CSS or initializing a library) runs after every client-side navigation when using <ClientRouter />.
Why Use Lifecycle Events?
With <ClientRouter />, navigating between pages does not trigger a full page reload. As a result, scripts that would normally run on DOMContentLoaded or on initial page load may not run again after navigation. To address this, Astro provides custom events like astro:page-load and astro:after-swap that you can listen for to re-run your logic after navigation [Script behavior with view transitions].
How to Use Lifecycle Events
Suppose you have a script that loads CSS or initializes a library. Instead of running it immediately, wrap it in an event listener for astro:page-load:
<script>
document.addEventListener("astro:page-load", () => {
// Place your logic here to load CSS or initialize your library
// For example, re-initialize a third-party widget or re-apply styles
});
</script>
- The
astro:page-loadevent fires after every navigation, including the initial page load and all subsequent navigations handled by<ClientRouter />[astro:page-load]. - This ensures your script logic is executed every time the user navigates to a new page, even without a full reload.
Example Use Case
If your external library script injects CSS or sets up UI components, you might need to call its initialization function after every navigation:
<script>
document.addEventListener("astro:page-load", () => {
if (window.MyLibrary) {
window.MyLibrary.init(); // or whatever method loads CSS/components
}
});
</script>
This approach ensures that your CSS and any dynamic behavior are consistently applied, regardless of how the user navigates your site.
In summary:
Listen for astro:page-load and place your initialization or CSS-loading logic inside the event handler. This guarantees your code runs after every client-side navigation with <ClientRouter />, solving the issue where CSS or scripts do not re-apply [Script behavior with view transitions].
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@weak pewter Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Let me check the knowledge base for you again. One moment! :books:
To use a script with a src and ensure it runs after every client-side navigation with <ClientRouter />, you have two main options according to the Astro documentation:
1. Use data-astro-rerun with is:inline
If you want an external script (via src) to re-execute after every navigation, add both is:inline and data-astro-rerun to your <script> tag:
<script is:inline data-astro-rerun src="<https://xxx/libraries/xxx.js"></script>>
This tells Astro to re-run the script on every client-side navigation, not just on the initial page load. This is the recommended way to ensure that scripts loaded via src are re-executed and can re-apply their CSS or other effects after navigation with <ClientRouter /> Script behavior with view transitions.
2. Using Lifecycle Events with Inline Logic
If you need to run specific logic (such as a function from an external library) after navigation, you can use an inline script that listens for the astro:page-load event and then calls the necessary function. However, this approach is for logic you control directly in the inline script, not for re-executing the entire external script file.
<script>
document.addEventListener("astro:page-load", () => {
// Call a function from your external library if it's already loaded
if (window.MyLibrary) {
window.MyLibrary.init();
}
});
</script>
But if your external script is not already loaded, you would need to dynamically load it inside this event handler, which is not directly covered in the official documentation.
Summary:
For external scripts loaded via src, use <script is:inline data-astro-rerun src="..."></script> to ensure they re-execute after every navigation with <ClientRouter /> Script behavior with view transitions. The documentation does not provide a built-in way to combine lifecycle events with a src attribute for automatic script loading.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@weak pewter Kapa.ai is still learning and improving, please let me know how I did by reacting below.
It doesn't work. So for now, there's no solution?
@long bronze It doesn't work. So for now, there's no solution?
Let me check the knowledge base for you again. One moment! :books:
Based on the official Astro documentation, the recommended way to ensure an external script (with a src attribute) re-executes after every client-side navigation with <ClientRouter /> is to use both the is:inline and data-astro-rerun attributes:
<script is:inline data-astro-rerun src="<https://xxx/libraries/xxx.js"></script>>
However, if this approach does not work for your use case—meaning the script is not re-executed or the CSS is still not applied after navigation—the knowledge sources do not provide an alternative built-in solution or workaround. The documentation does not mention any other method for reliably re-executing external scripts with a src after client-side navigation, nor does it describe a way to force external CSS (loaded via JS) to re-apply in this scenario Script behavior with view transitions.