I built a landing site using Angular. To make it SEO friendly, I had to do prerender it.
The landing page starts with an intro animation (using CSS’ animation
).
When I first load the page/full reload, the animation starts, and in the middle the app is being bootstrapped so ot restarts the animation again.
I was wondering if there’s a way to prevent the animations to reoccur. I know that there are few questions that might be similar to mine, but none of them helped me.
I have tried to solve this issue by:
- Adding
initialNavigation
inAppRoutingModule
:
@NgModule({
imports: [RouterModule.forRoot(routes, { initialNavigation: 'enabled'})],
exports: [RouterModule]
})
export class AppRoutingModule {
}
- Adding
TransferHttpCacheModule
andBrowserTransferStateModule
toAppModule
, andServerTransferStateModule
toAppServerModule
.
4
Answers
You could do it, however it might not be the answer you’re looking for.
First let’s see what happens when a SSR Angular app starts in the browser:
The browser receives the server-side rendered page. The HTML is rendered, including your animation, and it starts playing. Then at the bottom of the page, the angular script tags are parsed, and the JS for the app starts downloading.
While the app is downloading, the animation is playing.
When the app is downloaded, it bootstraps, and when it’s bootstrapped, it renders the whole DOM again, including your animation. During this process, the old animated elements are removed from the DOM, and then new animated elements are added. The animation starts playing the second time.
You can go around this in 2 ways:
either don’t start the animation until the app is loaded on the client (add the animation with a custom class when the app runs in a browser)
or move the animation outside of your app, embed it manually to the
index.html
– this way when the SSR re-render happens it will not be affected. (this way you can’t have the element inside your<app-root></app-root>
elements)Hope this helps!
Have you tried to save any indication of initial loading, for example with cookies as suggested.
And then wrap the animated element with
[@.disabled]="indication"
, it should look like this:It’s actually fairly simple – all you need to do is:
I’ve created a simple directive for this purpose. Just put it on any element that has a css animation e.g.
Here it is:
You can disable angular animations in a similar fashion.
Hope it’s of help to someone.
Import NoopAnimationsModule to the app.server.module.ts