Angular SSR: Optimización para SEO y Performance
10 de diciembre de 2025
Osman Jimenez
Angular SEO Performance
Server-Side Rendering en Angular
El SSR (Server-Side Rendering) en Angular mejora drásticamente el SEO y el tiempo de carga inicial. Aprende a implementarlo y optimizarlo correctamente.
Configuración Inicial
// Agregar SSR a proyecto existente
ng add @angular/ssr
// Ejecutar en modo SSR
npm run dev:ssr
npm run build:ssr
npm run serve:ssrManejo de APIs del Navegador
El código SSR se ejecuta en Node.js, donde no existen APIs del navegador:
import { isPlatformBrowser } from '@angular/common';
import { PLATFORM_ID, inject } from '@angular/core';
export class MyComponent {
private platformId = inject(PLATFORM_ID);
ngOnInit() {
if (isPlatformBrowser(this.platformId)) {
// Código que usa window, document, localStorage
const data = localStorage.getItem('key');
window.addEventListener('scroll', this.onScroll);
}
}
}TransferState para Evitar Doble Petición
import { TransferState, makeStateKey } from '@angular/platform-browser';
const USERS_KEY = makeStateKey('users');
export class UserService {
private transferState = inject(TransferState);
private http = inject(HttpClient);
getUsers(): Observable {
// Verificar si ya tenemos los datos del servidor
const cachedUsers = this.transferState.get(USERS_KEY, null);
if (cachedUsers) {
// Limpiar para evitar fugas de memoria
this.transferState.remove(USERS_KEY);
return of(cachedUsers);
}
// Hacer petición y guardar en TransferState
return this.http.get('/api/users').pipe(
tap(users => {
if (isPlatformServer(this.platformId)) {
this.transferState.set(USERS_KEY, users);
}
})
);
}
} Meta Tags Dinámicos para SEO
import { Meta, Title } from '@angular/platform-browser';
export class ProductDetailComponent {
private meta = inject(Meta);
private title = inject(Title);
ngOnInit() {
this.productService.getProduct(this.id).subscribe(product => {
// Título
this.title.setTitle(`${product.name} - Mi Tienda`);
// Meta tags
this.meta.updateTag({
name: 'description',
content: product.description
});
// Open Graph
this.meta.updateTag({
property: 'og:title',
content: product.name
});
this.meta.updateTag({
property: 'og:image',
content: product.imageUrl
});
this.meta.updateTag({
property: 'og:description',
content: product.description
});
// Twitter Card
this.meta.updateTag({
name: 'twitter:card',
content: 'summary_large_image'
});
});
}
}Prerendering de Rutas Estáticas
// angular.json
{
"projects": {
"my-app": {
"architect": {
"prerender": {
"options": {
"routes": [
"/",
"/about",
"/contact",
"/products/1",
"/products/2"
]
}
}
}
}
}
}Optimizaciones de Performance
1. Lazy Loading de Imágenes
![]()
2. Defer Loading de Componentes
@defer (on viewport) {
} @placeholder {
Cargando...
}Manejo de Errores en SSR
// server.ts
server.get('*', (req, res, next) => {
const { protocol, originalUrl, baseUrl, headers } = req;
commonEngine
.render({
bootstrap,
documentFilePath: indexHtml,
url: `${protocol}://${headers.host}${originalUrl}`,
publicPath: browserDistFolder,
providers: [
{ provide: APP_BASE_HREF, useValue: baseUrl }
]
})
.then((html) => res.send(html))
.catch((err) => {
console.error('SSR Error:', err);
res.status(500).send('Error rendering page');
});
});Testing SSR
// Verificar que el componente funciona en ambos entornos
describe('MyComponent SSR', () => {
it('should work on server', () => {
TestBed.configureTestingModule({
providers: [
{ provide: PLATFORM_ID, useValue: 'server' }
]
});
const fixture = TestBed.createComponent(MyComponent);
expect(fixture.componentInstance).toBeTruthy();
});
});Mejores Prácticas
- Evita código específico del navegador: Usa isPlatformBrowser
- Usa TransferState: Para evitar peticiones duplicadas
- Meta tags dinámicos: Actualiza SEO por ruta
- Prerender rutas estáticas: Para mejor performance
- Manejo de errores: Implementa fallbacks robustos
Conclusión
Angular SSR es esencial para aplicaciones que necesitan buen SEO y tiempos de carga rápidos. Con estas técnicas puedes implementar SSR de forma efectiva y evitar los problemas comunes.