Renderizado de componentes
El router-outlet es una directiva especial de Angular que actúa como un marcador de posición donde se renderiza dinámicamente el componente asociado a la ruta activa. Funciona como un contenedor que Angular utiliza para mostrar el componente correspondiente según la URL actual del navegador.
Cuando un usuario navega a una ruta específica, Angular busca en la configuración de rutas qué componente debe mostrar y lo renderiza automáticamente dentro del router-outlet. Este proceso es completamente dinámico y no requiere intervención manual del desarrollador.
Colocación en el template principal
Para utilizar router-outlet, simplemente lo añadimos como un elemento vacío en nuestro template principal, típicamente en el componente raíz de la aplicación:
<div class="app-container">
<header>
<h1>Mi Aplicación Angular</h1>
<nav>
<a routerLink="/home">Inicio</a>
<a routerLink="/about">Acerca de</a>
<a routerLink="/contact">Contacto</a>
</nav>
</header>
<main>
<router-outlet></router-outlet>
</main>
<footer>
<p>© 2025 Mi Aplicación</p>
</footer>
</div>
En este ejemplo, el contenido dinámico se renderizará exactamente donde hemos colocado <router-outlet></router-outlet>
, mientras que el header y footer permanecen fijos independientemente de la ruta activa.
Importación necesaria
Para usar router-outlet en componentes standalone, necesitamos importar RouterOutlet
desde @angular/router
:
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
@Component({
selector: 'app-root',
imports: [RouterOutlet],
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'mi-aplicacion';
}
Ejemplo práctico de layout
Consideremos una aplicación con las siguientes rutas configuradas:
// app.routes.ts
import { Routes } from '@angular/router';
import { HomeComponent } from './home.component';
import { AboutComponent } from './about.component';
import { ContactComponent } from './contact.component';
export const routes: Routes = [
{ path: 'home', component: HomeComponent },
{ path: 'about', component: AboutComponent },
{ path: 'contact', component: ContactComponent },
{ path: '', redirectTo: '/home', pathMatch: 'full' }
];
Con esta configuración:
- Cuando el usuario navega a
/home
: Angular renderizaHomeComponent
dentro del router-outlet - Cuando navega a
/about
: Reemplaza el contenido anterior conAboutComponent
- Cuando navega a
/contact
: MuestraContactComponent
en su lugar
El intercambio de componentes es instantáneo y mantiene el resto del layout intacto. Esto permite crear interfaces con navegación fluida donde solo cambia la sección principal de contenido.
Comportamiento del renderizado
Es importante entender que router-outlet funciona como un contenedor inteligente:
- Solo se renderiza un componente a la vez dentro de cada router-outlet
- El componente anterior se destruye completamente cuando se navega a una nueva ruta
- Cada componente renderizado mantiene su propio estado mientras está activo
- Angular gestiona automáticamente el ciclo de vida de los componentes (creación y destrucción)
<!-- Template del componente principal -->
<div class="layout">
<aside class="sidebar">
<!-- Contenido estático del sidebar -->
</aside>
<section class="content">
<!-- Aquí se renderiza dinámicamente el componente de la ruta activa -->
<router-outlet></router-outlet>
</section>
</div>
Esta separación entre contenido estático (sidebar) y contenido dinámico (router-outlet) es uno de los patrones más comunes en aplicaciones de página única, permitiendo mantener elementos de navegación y branding consistentes mientras se cambia el contenido principal según la ruta seleccionada.
Rutas anidadas
Las rutas anidadas permiten crear estructuras de navegación más complejas donde un componente padre puede tener su propio router-outlet para renderizar componentes hijos. Este patrón es especialmente útil cuando necesitamos crear secciones de la aplicación con su propia navegación interna.
Concepto básico de anidamiento
Una ruta anidada se produce cuando un componente que ya está siendo renderizado por un router-outlet tiene, a su vez, otro router-outlet interno. Esto crea una jerarquía de rutas donde el contenido se organiza en múltiples niveles.
Imagina una aplicación con una sección de administración que tiene sus propias subsecciones:
// Configuración básica de rutas anidadas
export const routes: Routes = [
{ path: 'admin', component: AdminComponent },
{ path: 'home', component: HomeComponent },
{ path: '', redirectTo: '/home', pathMatch: 'full' }
];
El componente AdminComponent
puede tener su propio sistema de navegación interno:
// admin.component.ts
import { Component } from '@angular/core';
import { RouterOutlet, RouterLink } from '@angular/router';
@Component({
selector: 'app-admin',
imports: [RouterOutlet, RouterLink],
template: `
<div class="admin-container">
<nav class="admin-nav">
<h2>Panel de Administración</h2>
<ul>
<li><a routerLink="/admin/users">Usuarios</a></li>
<li><a routerLink="/admin/settings">Configuración</a></li>
<li><a routerLink="/admin/reports">Informes</a></li>
</ul>
</nav>
<div class="admin-content">
<!-- Router-outlet secundario para contenido de admin -->
<router-outlet></router-outlet>
</div>
</div>
`
})
export class AdminComponent {}
Múltiples niveles de renderizado
En esta estructura, tenemos dos niveles de router-outlet:
- Router-outlet principal (en AppComponent): Renderiza AdminComponent cuando la ruta es
/admin
- Router-outlet secundario (en AdminComponent): Renderiza los componentes específicos de administración
Cuando un usuario navega a /admin/users
, Angular:
- Primero renderiza
AdminComponent
en el router-outlet principal - Después renderiza
UsersComponent
en el router-outlet interno del AdminComponent
<!-- Estructura visual resultante -->
<app-root>
<!-- Layout principal con header/footer fijos -->
<header>Navegación Principal</header>
<main>
<!-- Router-outlet principal -->
<app-admin>
<!-- Navegación interna de admin -->
<nav>Panel de Administración</nav>
<!-- Router-outlet secundario -->
<app-users>
<!-- Contenido específico de usuarios -->
</app-users>
</app-admin>
</main>
<footer>Footer fijo</footer>
</app-root>
Ejemplo práctico con dashboard
Consideremos un dashboard empresarial que necesita mostrar diferentes secciones:
// dashboard.component.ts
@Component({
selector: 'app-dashboard',
imports: [RouterOutlet, RouterLink],
template: `
<div class="dashboard">
<aside class="sidebar">
<h3>Dashboard</h3>
<nav>
<a routerLink="/dashboard/analytics">Analytics</a>
<a routerLink="/dashboard/sales">Ventas</a>
<a routerLink="/dashboard/inventory">Inventario</a>
</nav>
</aside>
<section class="main-content">
<router-outlet></router-outlet>
</section>
</div>
`,
styles: [`
.dashboard {
display: flex;
min-height: 500px;
}
.sidebar {
width: 250px;
background: #f5f5f5;
padding: 1rem;
}
.main-content {
flex: 1;
padding: 1rem;
}
`]
})
export class DashboardComponent {}
Ventajas del patrón anidado
Las rutas anidadas proporcionan varios beneficios importantes:
- Organización modular: Cada sección mantiene su propia lógica de navegación
- Reutilización: Los componentes padre pueden reutilizarse con diferentes contenidos
- Mantenimiento: Es más fácil mantener navegaciones complejas divididas en secciones
- UX consistente: Los usuarios mantienen el contexto visual del componente padre
Flujo de renderizado anidado
El proceso de renderizado con rutas anidadas funciona de manera secuencial:
- Paso 1: Angular identifica la ruta principal (
/dashboard
) - Paso 2: Renderiza
DashboardComponent
en el router-outlet principal - Paso 3: Identifica la subruta (
/analytics
) - Paso 4: Renderiza
AnalyticsComponent
en el router-outlet del dashboard
Cada router-outlet opera independientemente pero dentro del contexto de su componente padre, creando una experiencia de navegación cohesiva donde el layout principal se mantiene mientras cambia solo el contenido específico de cada sección.
Este patrón es fundamental para aplicaciones empresariales donde necesitamos estructuras de navegación complejas manteniendo una experiencia de usuario intuitiva y un código bien organizado.
Fuentes y referencias
Documentación oficial y recursos externos para profundizar en Angular
Documentación oficial de Angular
Alan Sastre
Ingeniero de Software y formador, CEO en CertiDevs
Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Angular es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.
Más tutoriales de Angular
Explora más contenido relacionado con Angular y continúa aprendiendo con nuestros tutoriales gratuitos.
Aprendizajes de esta lección
- Comprender el funcionamiento básico de router-outlet para renderizar componentes según la ruta activa.
- Aprender a colocar router-outlet en el template principal para mostrar contenido dinámico.
- Conocer cómo importar y utilizar RouterOutlet en componentes standalone.
- Entender el concepto y la implementación de rutas anidadas con múltiples niveles de router-outlet.
- Valorar las ventajas y el flujo de renderizado en aplicaciones con navegación compleja y jerárquica.