#View Transition with Motion
9 messages · Page 1 of 1 (latest)
Hi @snow maple. 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 View Transitions with <ClientRouter />, scripts may not re-run after page navigation as they would with full-page browser refreshes. This is likely why your Motion animations work on initial page load but stop working when navigating between pages.
To fix this issue, you need to ensure your Motion animations run after each page navigation by using Astro's lifecycle events. The most appropriate event to use is astro:page-load, which fires at the end of page navigation after the new page is visible and all blocking styles and scripts are loaded.
Here's how you can modify your Motion animation code:
<script>
document.addEventListener('astro:page-load', () => {
// Your Motion animation code here
// This will run on first page load and after every navigation
});
</script>
By wrapping your Motion initialization code in this event listener, your animations will be properly set up each time a new page loads during client-side navigation View transitions - Script behavior.
If you're using inline scripts, you can also add the data-astro-rerun attribute to force your script to re-execute after every transition:
<script is:inline data-astro-rerun>
// Your Motion animation code here
</script>
This attribute was added in Astro 4.5.0 and automatically makes the script run after each page transition View transitions - Script re-execution.
Remember that if your Motion code sets up global state, you'll need to account for the script potentially executing multiple times:
<script is:inline>
if (!window.motionInitialized) {
// Initialize your Motion animations
window.motionInitialized = true;
}
</script>
This approach ensures your Motion animations work consistently across all page navigations when using Astro's View Transitions.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@snow maple Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@lean latch I am using scripts but the data-astro-rerun doesn't appear to be working. Here is what I have:
<script is:inline data-astro-rerun>
import { animate, stagger } from 'motion'
// Run animation when the component mounts
document.addEventListener('DOMContentLoaded', () => {
const animateNav = () => {
animate(
'.nav-item',
{
opacity: [0, 1],
y: [-20, 0],
},
{
duration: 0.5,
delay: stagger(0.1),
}
)
}
animateNav()
})
</script>
Let me check the knowledge base for you again. One moment! :books:
I see the issue with your script. There are a couple of problems that are preventing your animations from working with view transitions.
First, when using is:inline, you can't use imports like import { animate, stagger } from 'motion'. The is:inline directive prevents Astro from processing, optimizing, or bundling the script, which means imports won't work as expected Script & Style Directives.
Second, the DOMContentLoaded event only fires once when the page initially loads, not after view transitions. With view transitions, you should use Astro's lifecycle events instead.
Here's how you can fix your script:
<script>
import { animate, stagger } from 'motion';
document.addEventListener('astro:page-load', () => {
animate(
'.nav-item',
{
opacity: [0, 1],
y: [-20, 0],
},
{
duration: 0.5,
delay: stagger(0.1),
}
);
});
</script>
This solution:
- Removes the
is:inlinedirective so imports can be processed correctly - Replaces
DOMContentLoadedwithastro:page-load, which fires after every page navigation with view transitions View transitions - Script behavior - Simplifies the code by directly calling the animation function within the event listener
The astro:page-load event will ensure your animation runs both on initial page load and after every navigation when using the <ClientRouter /> component View transitions - astro:page-load.