<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Mauricio Garcia</title>
    <description>The latest articles on Forem by Mauricio Garcia (@mauriciogc).</description>
    <link>https://forem.com/mauriciogc</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F355030%2F579217fc-1104-434d-b074-14d520e6a27e.png</url>
      <title>Forem: Mauricio Garcia</title>
      <link>https://forem.com/mauriciogc</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mauriciogc"/>
    <language>en</language>
    <item>
      <title>Next.js — Páginas, Rutas estáticas, dinámicas y anidadas</title>
      <dc:creator>Mauricio Garcia</dc:creator>
      <pubDate>Wed, 21 May 2025 23:23:12 +0000</pubDate>
      <link>https://forem.com/mauriciogc/nextjs-paginas-rutas-estaticas-dinamicas-y-anidadas-3da9</link>
      <guid>https://forem.com/mauriciogc/nextjs-paginas-rutas-estaticas-dinamicas-y-anidadas-3da9</guid>
      <description>&lt;h2&gt;
  
  
  Páginas con Next.js
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Next.js&lt;/em&gt; utiliza &lt;strong&gt;enrutamiento&lt;/strong&gt; &lt;strong&gt;basado&lt;/strong&gt; en el &lt;strong&gt;sistema&lt;/strong&gt; de &lt;strong&gt;archivos&lt;/strong&gt; , lo que significa que puedes usar &lt;strong&gt;carpetas y archivos para definir rutas&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Una &lt;strong&gt;página&lt;/strong&gt; en &lt;em&gt;Next.js&lt;/em&gt; representa una interfaz de usuario que se renderiza en una ruta específica del sitio [&lt;a href="https://nextjs.org/docs/app/getting-started/layouts-and-pages#creating-a-page" rel="noopener noreferrer"&gt;ref&lt;/a&gt;].&lt;/p&gt;

&lt;p&gt;Para crear una página, debes agregar un archivo &lt;code&gt;page.tsx&lt;/code&gt; dentro del directorio &lt;code&gt;/app&lt;/code&gt; y exportar un componente de React.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ExamplePage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Esta&lt;/span&gt; &lt;span class="nx"&gt;es&lt;/span&gt; &lt;span class="nx"&gt;una&lt;/span&gt; &lt;span class="nx"&gt;página&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;ejemplo&lt;/span&gt; &lt;span class="nx"&gt;en&lt;/span&gt; &lt;span class="nx"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota&lt;/strong&gt;: El proyecto genera una página por default en &lt;code&gt;_/app&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Crear una página
&lt;/h3&gt;

&lt;p&gt;Para crear una página nueva en Next.js, debes tener en cuenta los siguientes pasos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Crear una carpeta con el nombre de la ruta deseada&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dentro de esa carpeta, crea un archivo llamado &lt;code&gt;page.tsx&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Exporta un componente de React por defecto.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vamos a crear una página que va a estar disponible desde la ruta &lt;code&gt;http://localhost:3000/about&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Crea la carpeta y el archivo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;src/app/about/page.tsx&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dentro de &lt;code&gt;page.tsx&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/app/about/page.tsx&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;AboutPage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;p-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-2xl font-bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Acerca&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;Nosotros&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Esta&lt;/span&gt; &lt;span class="nx"&gt;es&lt;/span&gt; &lt;span class="nx"&gt;la&lt;/span&gt; &lt;span class="nx"&gt;página&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;información&lt;/span&gt; &lt;span class="nx"&gt;general&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Al iniciar el servidor (&lt;code&gt;npm run dev&lt;/code&gt;), podrás acceder a esta página visitando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;http://localhost:3000/about&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl974tqo3ivdkos6aph8e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl974tqo3ivdkos6aph8e.png" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Descarga el proyecto actual [&lt;a href="https://github.com/mauriciogc/next.js-15.3-1/tree/simple-page" rel="noopener noreferrer"&gt;ref&lt;/a&gt;] (branch: simple-page)&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Rutas en Next.js
&lt;/h2&gt;

&lt;p&gt;En &lt;em&gt;Next.js&lt;/em&gt;, cada &lt;strong&gt;carpeta&lt;/strong&gt; dentro de &lt;code&gt;/app&lt;/code&gt; &lt;strong&gt;representa una ruta&lt;/strong&gt; de la aplicación.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rutas estáticas
&lt;/h3&gt;

&lt;p&gt;Son páginas cuyas &lt;strong&gt;rutas no cambian&lt;/strong&gt;, están definidas. Por ejemplo: &lt;code&gt;/, /about, /contact, /faq, /ssg, etc.&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Ventajas de las rutas estáticas:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;SEO: Como son conocidas, se pueden generar como HTML estático.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pueden ser renderizadas con SSG (build), por lo que su carga será mucho más rápida.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Al ser estáticas no aceptan parámetros externos como las rutas dinámicas.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  ¿Cómo se crean?
&lt;/h4&gt;

&lt;p&gt;Las rutas &lt;em&gt;estáticas&lt;/em&gt; se crean exactamente igual que una página:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Crear una carpeta con el nombre de la ruta deseada&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dentro de esa carpeta, crea un archivo llamado &lt;code&gt;page.tsx&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Exporta un componente de React por defecto.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  ¿Cómo funcionan?
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Next.js&lt;/em&gt; con &lt;strong&gt;App Router&lt;/strong&gt; analiza la carpeta &lt;code&gt;/app&lt;/code&gt; y genera automáticamente las rutas, es decir al ejecutar &lt;code&gt;npm run dev&lt;/code&gt;, &lt;em&gt;Next.js&lt;/em&gt; hace lo siguiente:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Mapea todas las carpetas que estén dentro de &lt;code&gt;/app&lt;/code&gt; y tengan el archivo &lt;code&gt;page.tsx&lt;/code&gt; como rutas.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Genera el HTML y JavaScript necesario.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Decide si renderiza como &lt;strong&gt;CSR&lt;/strong&gt; (cliente), &lt;strong&gt;SSR&lt;/strong&gt; (tiempo real), &lt;strong&gt;SSG&lt;/strong&gt; (build) o según como hayas escrito el código.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota&lt;/strong&gt;: Los tipos de renderización los vamos a revisar a fondo más adelante.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Ejemplo
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;src/app/contact/page.tsx → /contact&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/app/contact/page.tsx&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ContactPage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;p-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-2xl font-bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Contáctanos&lt;/span&gt;&lt;span class="o"&gt;!!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;Estamos&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;ayudarte&lt;/span&gt; &lt;span class="p"&gt;:).&lt;/span&gt; &lt;span class="nx"&gt;Escríbenos&lt;/span&gt; &lt;span class="nx"&gt;si&lt;/span&gt; &lt;span class="nx"&gt;tienes&lt;/span&gt; &lt;span class="nx"&gt;alguna&lt;/span&gt; &lt;span class="nx"&gt;duda&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;sugerencia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Al iniciar el servidor (&lt;code&gt;npm run dev&lt;/code&gt;), podrás acceder a esta página visitando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;http://localhost:3000/contact&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm5wnneq4akz8pi969vno.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm5wnneq4akz8pi969vno.png" width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Rutas estáticas anidadas
&lt;/h3&gt;

&lt;p&gt;Las rutas estáticas anidadas no son otra cosa que un ruta estática que se encuentra &lt;strong&gt;dentro de otra carpeta estática&lt;/strong&gt;. Es decir, representa un &lt;strong&gt;nivel jerárquico más profundo&lt;/strong&gt;. Ejemplo: &lt;code&gt;products/mens, products/woman, docs/getting-started, etc&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Ventajas de las rutas estáticas
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Permite estructurar la app por secciones y subsecciones de forma clara y escalable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;La URLs son predecibles y amigables para motores de búsqueda (SEO-friendly).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Puedes tener layouts anidados para compartir diseño entre rutas relacionadas.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ideal para secciones grandes con multiples páginas y subsecciones (&lt;code&gt;/docs/..., /products/..., etc&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  ¿Cómo funcionan?
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Next.js&lt;/em&gt; con &lt;strong&gt;App Router&lt;/strong&gt; analiza la carpeta &lt;code&gt;/app&lt;/code&gt; y genera automáticamente las rutas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Mapea todas las carpetas y subcarpetas que estén dentro de &lt;code&gt;/app&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cada carpeta representa &lt;strong&gt;una parte del path en la URL&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Solo &lt;strong&gt;considera&lt;/strong&gt; una carpeta como parte de una &lt;strong&gt;ruta si &lt;em&gt;co-localiza&lt;/em&gt;&lt;/strong&gt; archivos especiales, el resto las ignora.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Ejemplo:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;src/app/dashboard/settings/page.tsx → /dashboard/settings&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/app/dashboard/settings/page.tsx&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;SettingsPage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;p-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-2xl font-bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Configuración&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Ajusta&lt;/span&gt; &lt;span class="nx"&gt;tus&lt;/span&gt; &lt;span class="nx"&gt;preferencias&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Al iniciar el servidor (&lt;code&gt;npm run dev&lt;/code&gt;), podrás acceder a esta página visitando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;http://localhost:3000/dashboard/settings&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ul7o8up69ayfkcm41pe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ul7o8up69ayfkcm41pe.png" width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Descarga el proyecto actual [&lt;a href="https://github.com/mauriciogc/next.js-15.3-1/tree/static-routes" rel="noopener noreferrer"&gt;ref&lt;/a&gt;] (branch: static-routes)&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ahora intenta acceder a:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;http://localhost:3000/dashboard&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podrás observar el mensaje de error: &lt;code&gt;404 | This page could not be found.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9a6d3yb9212yl18o3ozn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9a6d3yb9212yl18o3ozn.png" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;El comportamiento se le conoce como &lt;strong&gt;&lt;em&gt;colocation&lt;/em&gt;&lt;/strong&gt; [&lt;a href="https://nextjs.org/docs/app/getting-started/project-structure#colocation" rel="noopener noreferrer"&gt;ref&lt;/a&gt;], lo que significa que &lt;strong&gt;Next.js solo genera una ruta si la carpeta contiene archivos relevantes&lt;/strong&gt; (&lt;code&gt;page.tsx&lt;/code&gt; o &lt;code&gt;route.tsx&lt;/code&gt;) &lt;strong&gt;para esa ruta&lt;/strong&gt;. Así evita que carpetas vacías generen rutas innecesarias.&lt;/p&gt;

&lt;p&gt;Aunque la estructura está definida a través de carpetas, &lt;strong&gt;una ruta no es accesible públicamente&lt;/strong&gt; hasta que se agrega un archivo especial.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc5hmwmndjitpg8nhf8z7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc5hmwmndjitpg8nhf8z7.png" width="800" height="242"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La ruta se hace pública cuando devuelve una &lt;code&gt;page.tsx&lt;/code&gt; o &lt;code&gt;route.tsx&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpbumhdkvffvkso65f2cv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpbumhdkvffvkso65f2cv.png" width="800" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si una carpeta &lt;strong&gt;no contiene ninguno de los archivos especiales&lt;/strong&gt; que Next.js reconoce, será &lt;strong&gt;ignorada automáticamente&lt;/strong&gt; y &lt;strong&gt;no generará una ruta&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftunopbcptxz006o8ylvp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftunopbcptxz006o8ylvp.png" width="800" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esto ayuda a evitar errores y asegura que &lt;strong&gt;solo las carpetas válidas se conviertan en rutas accesibles&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota&lt;/strong&gt;: Aunque es posible colocar archivos no especiales (como componentes, estilos, funciones utilitarias o peticiones API) dentro del directorio &lt;code&gt;/app&lt;/code&gt;, &lt;strong&gt;no se recomienda hacerlo&lt;/strong&gt;. Como buena práctica, se sugiere mantener estos elementos &lt;strong&gt;fuera del directorio&lt;/strong&gt; &lt;code&gt;/app&lt;/code&gt;, en carpetas como &lt;code&gt;/components&lt;/code&gt;, &lt;code&gt;/lib&lt;/code&gt;, &lt;code&gt;/styles&lt;/code&gt;, etc., para mantener una estructura modular, limpia y más fácil de mantener.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Rutas dinámicas
&lt;/h3&gt;

&lt;p&gt;Son páginas que &lt;strong&gt;dependen&lt;/strong&gt; de un &lt;strong&gt;parámetro&lt;/strong&gt; &lt;strong&gt;variable&lt;/strong&gt;, como un ID o un nombre. Por ejemplo &lt;code&gt;/posts/1, /users/mau, /products/abc123, etc&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Ventajas de las rutas dinámicas
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Flexibilidad para representar contenido variable.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Evitar duplicar código ya que no es necesario hacer una página por ítem.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Escalabilidad total ya que a medida que la app crece, las rutas dinámicas escalan automáticamente sin necesidad de crear archivos nuevos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Soporte completo para SSR (contenido cambia frecuentemente), SSG (datos que no cambian) o CSR (necesitas JS del lado del cliente).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Libertad total para optimizar rendimiento, SEO y experiencia de usuario, según el caso.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  ¿Cómo se crean?
&lt;/h4&gt;

&lt;p&gt;Las rutas dinámicas se crean de forma muy similar a una ruta estática, con la diferencia de que la carpeta usa corchetes &lt;code&gt;[foldername]&lt;/code&gt; para definir un parámetro dinámico.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Crear una carpeta con el nombre de la ruta deseada, nombrandola entre corchetes &lt;code&gt;[foldername]&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dentro de esa carpeta, crea un archivo llamado &lt;code&gt;page.tsx&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Exporta un componente de React por defecto.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Accede al parámetro dinámico desde &lt;code&gt;params&lt;/code&gt; en el componente de página.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  ¿Cómo funcionan?
&lt;/h4&gt;

&lt;p&gt;Next.js con &lt;strong&gt;App Router&lt;/strong&gt; analiza la carpeta &lt;code&gt;/app&lt;/code&gt; y genera automáticamente las rutas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Mapea todas las carpetas que estén dentro de &lt;code&gt;/app&lt;/code&gt; y tengan el archivo &lt;code&gt;page.tsx&lt;/code&gt; como rutas.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Genera el HTML y JavaScript necesario.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Decide si renderiza como CSR (cliente), SSR (tiempo real), SSG (build) o según como hayas escrito el código.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cuando el usuario visita una página dinámica (&lt;code&gt;/posts/5&lt;/code&gt;), Next.js hace lo siguiente:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Detecta que &lt;code&gt;[id]&lt;/code&gt; es una ruta dinámica.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extrae el &lt;code&gt;5&lt;/code&gt; como parámetro &lt;code&gt;params.id&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ejecuta la lógica dentro del componente y renderiza la página.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Ejemplo
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;src/app/posts/[id]/page.tsx → /posts/:id&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/app/posts/[id]/page.tsx&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;PageParams&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// La propiedad params es asincrona, por lo que se debe de tratar como promesa&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;PageProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PageParams&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;PostPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;PageProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Desestructuramos el id de params, ya que es una promesa&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;p-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-2xl font-bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota&lt;/strong&gt;: En versiones anteriores a la &lt;strong&gt;14&lt;/strong&gt;, la propiedad &lt;code&gt;params&lt;/code&gt; es &lt;strong&gt;síncrona&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Aunque Next.js &lt;strong&gt;15&lt;/strong&gt; aún mantiene compatibilidad con este comportamiento, &lt;strong&gt;se recomienda utilizar&lt;/strong&gt; &lt;code&gt;params&lt;/code&gt; &lt;strong&gt;de forma asíncrona.&lt;/strong&gt; Ya que el comportamiento síncrono será eliminado en futuras versiones.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Al iniciar el servidor (&lt;code&gt;npm run dev&lt;/code&gt;), podrás acceder a esta página visitando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;http://localhost:3000/post/uno&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4hk1eauxboan63j8gfor.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4hk1eauxboan63j8gfor.gif" width="631" height="473"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;app/posts/[id]/page.js → /posts/a → { id&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;a'&lt;/span&gt; &lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="s"&gt;app/posts/[id]/page.js → /posts/b → { id&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;b'&lt;/span&gt; &lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="s"&gt;app/posts/[id]/page.js → /posts/3 → { id&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3'&lt;/span&gt; &lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Rutas dinámicas anidadas
&lt;/h3&gt;

&lt;p&gt;Next.js permite tener en una ruta diferentes niveles dinámicos. Por ejemplo: &lt;code&gt;/blog/javascript/arrays&lt;/code&gt;, &lt;code&gt;/blog/css/flexbox&lt;/code&gt; , &lt;code&gt;/users/mau/posts/1&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Ventajas de las rutas dinámicas anidadas
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Son ideales cuando se tiene que representar relaciones (padre/hijo).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mejoran exponencialmente el contexto de la URL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Su mayor uso es en productos de tienda, comentarios dentro de un post.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Permite acceder a múltiples parámetros (&lt;code&gt;params&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  ¿Cómo se crean?
&lt;/h4&gt;

&lt;p&gt;Siguiendo la misma lógica de una ruta dinámica:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Crear dentro de la carpeta &lt;code&gt;src/app&lt;/code&gt; la estructura de carpetas correspondiente a la ruta deseada, definiendo entre &lt;code&gt;[foldername]&lt;/code&gt; las carpetas necesarias que van a ser el parámetro dinámico.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dentro de esa carpeta o de las carpetas que queremos que sean rutas públicas, se debe crear un archivo llamado &lt;code&gt;page.tsx&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Exporta un componente de React por defecto.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Accede a los parámetros dinámicos desde &lt;code&gt;params&lt;/code&gt; en el componente de página.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  ¿Cómo funcionan?
&lt;/h4&gt;

&lt;p&gt;Next.js con App Router analiza la carpeta &lt;code&gt;/app&lt;/code&gt; y genera automáticamente las rutas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Mapea todas las carpetas y subcarpetas que estén dentro de &lt;code&gt;/app&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cada carpeta representa una parte del path en la URL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Si una carpeta tiene un nombre entre corchetes (&lt;code&gt;[param]&lt;/code&gt;), se trata como un &lt;strong&gt;segmento dinámico&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Solo considera una carpeta como parte de una ruta si co-localiza archivos especiales, el resto las ignora.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Ejemplo
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;src/app/blog/[category]/posts/[name]/page.tsx → /blog/javascript/posts/arrays&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/app/blog/[category]/posts/[name]/page.tsx&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;PageParams&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// La propiedad params es asincrona, por lo que se debe de tratar como promesa&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;PageProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PageParams&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;BlogPostPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;PageProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Desestructuramos los parámetros de la promesa&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;p-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-2xl font-bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-lg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Categoría&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Al iniciar el servidor (&lt;code&gt;npm run dev&lt;/code&gt;), podrás acceder a esta página visitando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;http://localhost:3000/blog/javascript/posts/arrays&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsnl2ym6i85sgk7979wb3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsnl2ym6i85sgk7979wb3.gif" width="631" height="473"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;src/app/blog/[category]/posts/[name]/page.tsx&lt;/span&gt;
&lt;span class="s"&gt;→ /blog/javascript/posts/nodejs-introduction&lt;/span&gt;
&lt;span class="s"&gt;→ { category&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;javascript'&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;nodejs-introduction'&lt;/span&gt; &lt;span class="err"&gt;}&lt;/span&gt;


&lt;span class="s"&gt;src/app/blog/[category]/posts/[name]/page.tsx&lt;/span&gt;
&lt;span class="s"&gt;→ /blog/css/posts/flexbox&lt;/span&gt;
&lt;span class="s"&gt;→ { category&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;javascript'&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;flexbox'&lt;/span&gt; &lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Descarga el proyecto actual [&lt;a href="https://github.com/mauriciogc/next.js-15.3-1/tree/dynamic-routes" rel="noopener noreferrer"&gt;ref&lt;/a&gt;] (branch: dynamic-routes)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recuerda&lt;/strong&gt;: que si intentas acceder a &lt;code&gt;/blog&lt;/code&gt; o &lt;code&gt;/blog/[category]&lt;/code&gt; o &lt;code&gt;/blog/[category]/posts&lt;/code&gt; saldrá el mensaje: &lt;code&gt;404 | This page could not be found.&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Hasta este punto, ya sabes cómo &lt;strong&gt;crear páginas en Next.js&lt;/strong&gt;, conoces las &lt;strong&gt;rutas dinámicas&lt;/strong&gt; y &lt;strong&gt;rutas dinámicas anidadas&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>dynamicroutes</category>
      <category>staticroutes</category>
      <category>simplepage</category>
    </item>
    <item>
      <title>JavaScript - ES9 (ECMAScript 2018) - Parte I</title>
      <dc:creator>Mauricio Garcia</dc:creator>
      <pubDate>Mon, 19 May 2025 21:38:33 +0000</pubDate>
      <link>https://forem.com/mauriciogc/javascript-es9-ecmascript-2018-parte-i-33ko</link>
      <guid>https://forem.com/mauriciogc/javascript-es9-ecmascript-2018-parte-i-33ko</guid>
      <description>&lt;h3&gt;
  
  
  Temario
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;&lt;em&gt;Introducción&lt;/em&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;em&gt;Nuevas Características&lt;/em&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Rest y Spread Properties para Objetos
&lt;/li&gt;
&lt;li&gt;Asynchronous Iteration (for await…of)
&lt;/li&gt;
&lt;li&gt;Promise.prototype.finally&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  i. Introducción
&lt;/h2&gt;

&lt;p&gt;Vamos a ver la primera parte de &lt;strong&gt;novedades&lt;/strong&gt; que nos trae la edición &lt;strong&gt;ES9&lt;/strong&gt; (&lt;em&gt;ES2018&lt;/em&gt;) de &lt;em&gt;JavaScript&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ten en cuenta que &lt;strong&gt;no todos los navegadores modernos admiten de forma nativa todas las funcionalidades “nuevas” de JavaScript&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Antes de utilizar alguna de ellas en entornos productivos, &lt;strong&gt;verifica la compatibilidad en los navegadores objetivo&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Si estás utilizando un &lt;strong&gt;transpilador como Babel&lt;/strong&gt; o algún sistema de build moderno (por ejemplo, Vite, Webpack con configuración adecuada o Next.js con configuración predeterminada), &lt;strong&gt;no deberías preocuparte&lt;/strong&gt;, ya que estas herramientas se encargan de transpilar el código a versiones compatibles con navegadores más antiguos.&lt;/p&gt;

&lt;p&gt;Aunque la mayoría de estas funcionalidades ya cuentan con un &lt;strong&gt;amplio soporte en los navegadores actuales&lt;/strong&gt;, siempre es recomendable hacer una validación explícita antes de lanzar a producción.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ii. Nuevas Características
&lt;/h2&gt;

&lt;h3&gt;
  
  
  01. Rest [&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring#rest_in_object_destructuring" rel="noopener noreferrer"&gt;ref&lt;/a&gt;] y Spread [&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#spread_in_object_literals" rel="noopener noreferrer"&gt;ref&lt;/a&gt;] Properties para Objetos
&lt;/h3&gt;

&lt;p&gt;Desde ECMAScript 2015 (ES6), la sintaxis &lt;code&gt;...&lt;/code&gt; ya se utilizaba ampliamente en JavaScript para trabajar con &lt;strong&gt;arreglos&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;...spread&lt;/code&gt;: para copiar o combinar arrays.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;...rest&lt;/code&gt;: para capturar elementos restantes al desestructurar.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;  

&lt;span class="c1"&gt;// Spread: copia propiedades  &lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newArr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;   
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newArr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// [1, 2, 3, 4]  &lt;/span&gt;

&lt;span class="c1"&gt;// Rest: extrae las propiedades  &lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 1  &lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// [2, 3]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sin embargo, esta sintaxis &lt;strong&gt;no era compatible con objetos&lt;/strong&gt;, lo que forzaba a los desarrolladores a usar métodos como &lt;code&gt;Object.assign()&lt;/code&gt; para copiar, clonar o fusionar objetos.&lt;/p&gt;

&lt;p&gt;ECMAScript 2018 vino a resolver esto al &lt;strong&gt;extender la capacidad&lt;/strong&gt; de &lt;code&gt;...rest&lt;/code&gt; y &lt;code&gt;...spread&lt;/code&gt; a &lt;strong&gt;objetos&lt;/strong&gt;, con una sintaxis similar pero adaptada para trabajar con claves y valores. Esto permite:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Extraer propiedades restantes de un objeto (&lt;code&gt;rest&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  Clonar o combinar objetos (&lt;code&gt;spread&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Principales características —&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Sintaxis limpia y declarativa para operaciones comunes con objetos.&lt;/li&gt;
&lt;li&gt;  Funciona con propiedades enumerables propias (&lt;code&gt;own enumerable&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  Compatible con desestructuración y funciones.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ventajas —&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Reemplaza la necesidad de &lt;code&gt;Object.assign&lt;/code&gt; para copias superficiales.&lt;/li&gt;
&lt;li&gt;  Permite evitar mutaciones accidentales.&lt;/li&gt;
&lt;li&gt;  Mejora la legibilidad y expresividad del código moderno.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;¿Dónde se usa? —&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Filtrar un dato antes de enviar a una API (si no es necesario).&lt;/li&gt;
&lt;li&gt;  Separar datos para audit logs o sistemas de monitoreo.&lt;/li&gt;
&lt;li&gt;  Configuración de aplicaciones (&lt;code&gt;theme&lt;/code&gt;, &lt;code&gt;locale&lt;/code&gt;, &lt;code&gt;features&lt;/code&gt;, etc.).&lt;/li&gt;
&lt;li&gt;  Formularios donde el usuario modifica los valores por defecto.&lt;/li&gt;
&lt;li&gt;  Composición de props en React.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Sintaxis —&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obj1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;  

&lt;span class="c1"&gt;// Spread: copia propiedades de obj  &lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obj2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;obj1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;   
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// { a: 1, b: 2, c: 3 }  &lt;/span&gt;

&lt;span class="c1"&gt;// Rest: extrae las propiedades restantes  &lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;obj2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 1  &lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// { b: 2, c: 3 }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;¿Cómo funciona internamente? —&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Durante la desestructuración:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  El motor recopila las propiedades no extraídas en un nuevo objeto (&lt;code&gt;[[Rest]]&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;Spread&lt;/code&gt; es una forma sintáctica de llamar internamente a &lt;code&gt;Object.assign({}, ...)&lt;/code&gt; con preservación del orden&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ejemplo 1 — Desestructuración con &lt;code&gt;rest&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;z&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;  
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 1  &lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// { y: 2, z: 3 }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Donde:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;const { x, ...rest } = obj;&lt;/code&gt; toma la propiedad &lt;code&gt;x&lt;/code&gt; y crea una nueva variable llamada &lt;code&gt;rest&lt;/code&gt; que contiene &lt;strong&gt;todas las propiedades restantes&lt;/strong&gt; del objeto original.&lt;/li&gt;
&lt;li&gt;  En este caso, &lt;code&gt;rest&lt;/code&gt; es un nuevo objeto &lt;code&gt;{ y: 2, z: 3 }&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Útil cuando&lt;/strong&gt;: Deseas acceder a una o dos propiedades específicas y pasar el resto a otro componente, función o API.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Ejemplo 2 — Desestructuración desde los &lt;code&gt;params&lt;/code&gt; de la función&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;logUser&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;userInfo&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ID:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ID: 42  &lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Datos:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;userInfo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Datos: { name: 'Mauricio', role: 'user' }  &lt;/span&gt;
  &lt;span class="c1"&gt;// ...  &lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;  

&lt;span class="nf"&gt;logUser&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mauricio&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Donde: Desestructuramos el objeto para extraer &lt;code&gt;id&lt;/code&gt; y dejamos el resto (&lt;code&gt;name&lt;/code&gt;, &lt;code&gt;role&lt;/code&gt;) dentro de &lt;code&gt;userInfo&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Útil cuando&lt;/strong&gt;: Deseas separar &lt;strong&gt;identificadores o metadatos&lt;/strong&gt; de los datos operativos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Ejemplo 3 — Overriding de configuraciones&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;defaults&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;grid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;  
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userSettings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;list&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;  

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;finalConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;defaults&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;userSettings&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;  
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;finalConfig&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// { theme: 'dark', layout: 'list' }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Donde:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Se combinan dos objetos (&lt;code&gt;defaults&lt;/code&gt; y &lt;code&gt;userSettings&lt;/code&gt;) con &lt;code&gt;spread&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Las propiedades del segundo (&lt;code&gt;userSettings&lt;/code&gt;) &lt;strong&gt;sobrescriben&lt;/strong&gt; las del primero si coinciden.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ejemplo 4 — React: Composición de props con spread&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&amp;gt;; &lt;/span&gt;&lt;span class="err"&gt; 
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;  

&lt;span class="c1"&gt;// Uso:  &lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;btn-primary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;  
  &lt;span class="nx"&gt;Guardar&lt;/span&gt;  
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Donde: Separamos &lt;code&gt;children&lt;/code&gt; para controlarlo, y propagamos el resto (&lt;code&gt;className&lt;/code&gt;, &lt;code&gt;onClick&lt;/code&gt;, etc.).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Útil ya que:&lt;/strong&gt; Es un patrón común en componentes reutilizables para no “re-declarar” cada prop.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Ejemplo 5 — Filtrado de campos sensibles&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;removeSensitiveFields&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ssn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;safeData&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;safeData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;  

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sanitized&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;removeSensitiveFields&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;  
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;john@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;123456&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
  &lt;span class="na"&gt;ssn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;999-99-9999&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
&lt;span class="p"&gt;});&lt;/span&gt;  

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sanitized&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// { name: 'John', email: 'john@example.com' }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Donde: Antes de mostrar o guardar el objeto en logs, se eliminan campos sensibles con &lt;code&gt;rest&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ejemplo 6 — Merging de resultados API + locale override&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;apiResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Avengers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Superhero movie&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
  &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;8.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
&lt;span class="p"&gt;};&lt;/span&gt;  

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;localeOverrides&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Los Vengadores&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
&lt;span class="p"&gt;};&lt;/span&gt;  

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;finalData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;apiResponse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;localeOverrides&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;  
&lt;span class="c1"&gt;// { title: 'Los Vengadores', description: 'Superhero movie', rating: 8.7 }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Donde: Usamos &lt;code&gt;spread&lt;/code&gt; para adaptar el contenido a distintos idiomas o preferencias sin modificar el resultado original.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Riesgos comunes —&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ejemplo 1— &lt;code&gt;Spread&lt;/code&gt; no aplica como copia profunda&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;original&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mauricio&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
    &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
  &lt;span class="p"&gt;},&lt;/span&gt;  
  &lt;span class="na"&gt;active&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
&lt;span class="p"&gt;};&lt;/span&gt;  

&lt;span class="c1"&gt;// "Clonamos"  &lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;copy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;original&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;  

&lt;span class="c1"&gt;// Modificamos una propiedad del objeto anidado  &lt;/span&gt;
&lt;span class="nx"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;55&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 55  &lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;original&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 55 - también cambió el original!!!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aunque &lt;code&gt;copy&lt;/code&gt; parece una copia nueva de &lt;code&gt;original&lt;/code&gt;, &lt;strong&gt;la propiedad &lt;code&gt;user&lt;/code&gt; sigue siendo la misma referencia&lt;/strong&gt; en ambos objetos. Esto ocurre porque &lt;code&gt;...original&lt;/code&gt; solo hace &lt;strong&gt;shallow copy&lt;/strong&gt;, es decir:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Copia propiedades &lt;strong&gt;de primer nivel&lt;/strong&gt; (clave/valor).&lt;/li&gt;
&lt;li&gt;  Si ese valor es &lt;strong&gt;un objeto&lt;/strong&gt;, &lt;strong&gt;la referencia&lt;/strong&gt; se copia, no el contenido.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Si necesitas una copia &lt;strong&gt;profunda&lt;/strong&gt; (deep copy), debes usar una estrategia adicional como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deepCopy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;original&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;  

&lt;span class="nx"&gt;deepCopy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;55&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deepCopy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 55  &lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;original&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 40&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Ejemplo 2—&lt;code&gt;rest&lt;/code&gt; no aplica como copia profunda&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;original&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Angie&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
    &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
  &lt;span class="p"&gt;},&lt;/span&gt;  
  &lt;span class="na"&gt;active&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
&lt;span class="p"&gt;};&lt;/span&gt;  

&lt;span class="c1"&gt;// Usamos rest para separar propiedades  &lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;original&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  

&lt;span class="c1"&gt;// Modificamos el objeto anidado en `rest`  &lt;/span&gt;
&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 21  &lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;original&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 21 - también cambió el original!!!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  El operador &lt;code&gt;...rest&lt;/code&gt; creó un nuevo objeto con todas las propiedades &lt;strong&gt;excepto &lt;code&gt;active&lt;/code&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  Sin embargo, la propiedad &lt;code&gt;user&lt;/code&gt; dentro de &lt;code&gt;rest&lt;/code&gt; sigue siendo la &lt;strong&gt;misma referencia&lt;/strong&gt; que en &lt;code&gt;original&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Si deseas evitar ese riesgo, deberías hacer una &lt;strong&gt;deep copy manual o asistida&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;original&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;safeRest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
  &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="c1"&gt;// copia anidada  &lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;  

&lt;span class="nx"&gt;safeRest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;safeRest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 21  &lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;original&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 35&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Soporte —&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;rest&lt;/code&gt; [&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring#rest_in_object_destructuring" rel="noopener noreferrer"&gt;ref&lt;/a&gt;], [&lt;a href="https://caniuse.com/mdn-javascript_operators_destructuring_rest_in_objects" rel="noopener noreferrer"&gt;ref&lt;/a&gt;]&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;spread&lt;/code&gt; [&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#spread_in_object_literals" rel="noopener noreferrer"&gt;ref&lt;/a&gt;], [&lt;a href="https://caniuse.com/mdn-javascript_operators_spread_spread_in_object_literals" rel="noopener noreferrer"&gt;ref&lt;/a&gt;]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;A considerar —&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  No hace copia profunda (shallow copy).&lt;/li&gt;
&lt;li&gt;  Solo propiedades propias, no del prototipo.&lt;/li&gt;
&lt;li&gt;  Si hay propiedades repetidas, la última sobrescribe.&lt;/li&gt;
&lt;li&gt;  Usa spread/rest con precaución: no reemplaza lógica de validación profunda.&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  02. Asynchronous Iteration (&lt;code&gt;for await...of&lt;/code&gt;) [&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of" rel="noopener noreferrer"&gt;ref&lt;/a&gt;]
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;for await...of&lt;/code&gt; permite iterar asincrónicamente sobre objetos &lt;strong&gt;async iterables&lt;/strong&gt; (como streams, APIs paginadas, generadores async, etc.).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Principales características —&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Funciona sobre objetos con &lt;code&gt;Symbol.asyncIterator&lt;/code&gt;[&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator" rel="noopener noreferrer"&gt;ref&lt;/a&gt;].&lt;/li&gt;
&lt;li&gt;  Pausa la ejecución hasta que cada &lt;code&gt;Promise&lt;/code&gt; se resuelve.&lt;/li&gt;
&lt;li&gt;  Se puede usar dentro de funciones &lt;code&gt;async&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ventajas —&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Facilita el trabajo con flujos de datos asincrónicos.&lt;/li&gt;
&lt;li&gt;  Código más limpio comparado con &lt;code&gt;.then()&lt;/code&gt; o &lt;code&gt;forEach + async&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Sintaxis —&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;asyncIterable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;asyncIterator&lt;/span&gt;&lt;span class="p"&gt;]()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
      &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;uno&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
      &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
      &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tres&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
    &lt;span class="p"&gt;},&lt;/span&gt;  
  &lt;span class="p"&gt;};&lt;/span&gt;  

  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;await &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;asyncIterable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
  &lt;span class="p"&gt;}&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explicando la sintaxis —&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paso 1:&lt;/strong&gt; Declaración de una &lt;strong&gt;función&lt;/strong&gt; &lt;strong&gt;async&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota&lt;/strong&gt;: Toda función &lt;code&gt;async&lt;/code&gt; devuelve automáticamente una &lt;strong&gt;promesa&lt;/strong&gt; y nos permite usar &lt;code&gt;await&lt;/code&gt; dentro de ella.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Paso 2:&lt;/strong&gt; Crear un objeto con un &lt;strong&gt;async iterable&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;asyncIterable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;asyncIterator&lt;/span&gt;&lt;span class="p"&gt;]()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;uno&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tres&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
  &lt;span class="p"&gt;},&lt;/span&gt;  
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Donde:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Al llamarse &lt;code&gt;asyncIterable[Symbol.asyncIterator]()&lt;/code&gt;, devuelve un &lt;strong&gt;AsyncGenerator (objeto asincrónicamente iterable)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  Este generador produce (&lt;code&gt;yield&lt;/code&gt;) valores uno a uno, como una secuencia.&lt;/li&gt;
&lt;li&gt;  Cada &lt;code&gt;yield&lt;/code&gt; se envuelve automáticamente en una &lt;code&gt;Promise&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Paso 3:&lt;/strong&gt; Usar &lt;code&gt;for await...of&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;await &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;asyncIterable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Donde:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Itera &lt;strong&gt;de manera asincrónica&lt;/strong&gt; sobre un objeto que implemente &lt;code&gt;Symbol.asyncIterator&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Espera con &lt;code&gt;await&lt;/code&gt; a que cada &lt;code&gt;yield&lt;/code&gt; produzca un valor.&lt;/li&gt;
&lt;li&gt;  Asigna ese valor a &lt;code&gt;val&lt;/code&gt; y ejecuta el cuerpo del bloque &lt;code&gt;console.log(val)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Resumiendo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;for await&lt;/code&gt;&lt;/strong&gt; llama a &lt;strong&gt;&lt;code&gt;asyncIterator()&lt;/code&gt;&lt;/strong&gt; y entra al generador.&lt;/li&gt;
&lt;li&gt;  Primer &lt;strong&gt;&lt;code&gt;yield&lt;/code&gt;&lt;/strong&gt; — &lt;code&gt;"uno"&lt;/code&gt; se resuelve y se imprime.&lt;/li&gt;
&lt;li&gt;  Segundo &lt;strong&gt;&lt;code&gt;yield&lt;/code&gt;&lt;/strong&gt; — &lt;code&gt;"dos"&lt;/code&gt; se resuelve y se imprime.&lt;/li&gt;
&lt;li&gt;  Tercer &lt;strong&gt;&lt;code&gt;yield&lt;/code&gt;&lt;/strong&gt; — &lt;code&gt;"tres"&lt;/code&gt; se resuelve y se imprime.&lt;/li&gt;
&lt;li&gt;  Generador finaliza — &lt;strong&gt;&lt;code&gt;done: true&lt;/code&gt;&lt;/strong&gt; el bucle termina.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ejemplo 1: Delays simulados&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;delayedValues&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;delays&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;  
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ms&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;delays&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;  
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
  &lt;span class="p"&gt;}&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;  

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;logDelays&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;await &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ms&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nf"&gt;delayedValues&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Esperado: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;ms`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
  &lt;span class="p"&gt;}&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;  

&lt;span class="nf"&gt;logDelays&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Donde:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;delayedValues&lt;/code&gt; es un &lt;strong&gt;generador asincrónico&lt;/strong&gt; (&lt;code&gt;async function*&lt;/code&gt;) que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Espera 4s, luego devuelve &lt;code&gt;4000&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Espera 2s, luego devuelve &lt;code&gt;2000&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Espera 3s, luego devuelve &lt;code&gt;3000&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;logDelays&lt;/code&gt; usa &lt;code&gt;for await...of&lt;/code&gt; para:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Iterar sobre cada valor generado por &lt;code&gt;delayedValues&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Esperar que cada &lt;code&gt;Promise&lt;/code&gt; se resuelva antes de continuar.&lt;/li&gt;
&lt;li&gt;  Imprimir: &lt;code&gt;Esperado: 4000ms&lt;/code&gt;, &lt;code&gt;Esperado: 2000ms&lt;/code&gt;, &lt;code&gt;Esperado: 3000ms&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhnk7jwb34qp6wvczu7vj.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhnk7jwb34qp6wvczu7vj.gif" alt="Image description" width="631" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Útil para:&lt;/strong&gt; simular tareas asincrónicas que se resuelven en tiempos diferentes (como llamadas a APIs que tardan distinto).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Ejemplo 2 — Paginación de películas populares con TMDb + &lt;code&gt;for await...of&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;TU API KEY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BASE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.themoviedb.org/3/movie/popular&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchMoviesPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;BASE_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;?language=en-US&amp;amp;page=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;  
  &lt;span class="p"&gt;});&lt;/span&gt;  

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Error HTTP &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;  

&lt;span class="c1"&gt;// Generador que devuelve todas las películas de TMDb  &lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;fetchAllPopularMovies&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;maxPages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
  &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;maxPages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="c1"&gt;// Invocamos la función que devuelve las películas de la página actual  &lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchMoviesPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
    &lt;span class="c1"&gt;// Recorremos los resultados de la página actual y devolvemos la película actual  &lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;movie&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
      &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;movie&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
    &lt;span class="p"&gt;}&lt;/span&gt;  

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;total_pages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
    &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
  &lt;span class="p"&gt;}&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;  

&lt;span class="c1"&gt;// Función principal que muestra las películas de TMDb  &lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Películas populares de TMDb:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;await &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;movie&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nf"&gt;fetchAllPopularMovies&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`= &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;movie&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; (&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;movie&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;release_date&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
  &lt;span class="p"&gt;}&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;  

&lt;span class="c1"&gt;// Llamamos a la función principal  &lt;/span&gt;
&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Donde:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;fetchAllPopularMovies()&lt;/code&gt; es un &lt;strong&gt;async generator&lt;/strong&gt; que va página por página.&lt;/li&gt;
&lt;li&gt;  Usa &lt;code&gt;yield&lt;/code&gt; para entregar &lt;strong&gt;una película a la vez&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;main()&lt;/code&gt; consume las películas una por una con &lt;code&gt;for await...of&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjoma4svz3lj6eslxqw67.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjoma4svz3lj6eslxqw67.gif" alt="Image description" width="631" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Útil para:&lt;/strong&gt; Procesamiento en batch, consolas, scripts backend, testing, pre-fetch de datos al montar componentes en Next.js.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Soporte —&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;for await…of&lt;/code&gt; [&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of" rel="noopener noreferrer"&gt;ref&lt;/a&gt;], [&lt;a href="https://caniuse.com/mdn-javascript_statements_for_await_of" rel="noopener noreferrer"&gt;ref&lt;/a&gt;]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;A considerar —&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Solo puede &lt;strong&gt;usarse&lt;/strong&gt; &lt;strong&gt;dentro de funciones &lt;code&gt;async&lt;/code&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  Ideal para &lt;strong&gt;procesar&lt;/strong&gt; &lt;strong&gt;streams&lt;/strong&gt;, resultados &lt;strong&gt;paginados&lt;/strong&gt;, o &lt;strong&gt;APIs&lt;/strong&gt; con espera.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;No mezclarlo&lt;/strong&gt; con &lt;strong&gt;&lt;code&gt;.map()&lt;/code&gt;&lt;/strong&gt; o &lt;strong&gt;&lt;code&gt;.forEach()&lt;/code&gt;&lt;/strong&gt; si cada paso depende del anterior.&lt;/li&gt;
&lt;li&gt;  Prefiere &lt;code&gt;for await...of&lt;/code&gt; cuando el orden importa y hay espera real.&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  03.Promise.prototype.finally
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;.finally()&lt;/code&gt; es un nuevo método en la cadena de Promesas que se ejecuta &lt;strong&gt;después de que la promesa se resuelve o rechaza&lt;/strong&gt;, &lt;strong&gt;sin modificar el valor original&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Principales características —&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Se ejecuta siempre, sin importar si fue &lt;code&gt;.then&lt;/code&gt; o &lt;code&gt;.catch&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  No cambia el resultado de la promesa.&lt;/li&gt;
&lt;li&gt;  Ideal para limpiar recursos o resetear estados.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ventajas —&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Reemplaza patrones repetitivos como duplicar &lt;code&gt;setLoading(false)&lt;/code&gt; en &lt;code&gt;.then&lt;/code&gt; y &lt;code&gt;.catch&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Mejora la claridad y estructura del código asincrónico.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Sintaxis —&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;  
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Petición finalizada&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  Se ejecuta &lt;strong&gt;después&lt;/strong&gt; de &lt;code&gt;.then()&lt;/code&gt; o &lt;code&gt;.catch()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  No recibe parámetros.&lt;/li&gt;
&lt;li&gt;  Retorna una promesa.&lt;/li&gt;
&lt;li&gt;  Si lanzas un error o devuelves una promesa rechazada dentro de &lt;code&gt;.finally()&lt;/code&gt;, &lt;strong&gt;ese error reemplaza el flujo&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ejemplo 1 — Simulación de espera&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;simulateRequest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;success&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
    &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
      &lt;span class="nx"&gt;success&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Operación exitosa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Ocurrió un error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
  &lt;span class="p"&gt;});&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;  

&lt;span class="nf"&gt;simulateRequest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;entra a finally&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbnbtczvmte1nbogwwyzs.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbnbtczvmte1nbogwwyzs.gif" alt="Image description" width="631" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ejemplo 2 — Ocultar un loader en React&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ProfileProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
  &lt;span class="nl"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;  

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ProfileLoader&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setProfile&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ProfileProps&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
    &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://jsonplaceholder.typicode.com/users/1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error al cargar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  
      &lt;span class="p"&gt;})&lt;/span&gt;  
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setProfile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;  
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;  

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Cargando&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&amp;gt;; &lt;/span&gt;&lt;span class="err"&gt; 
&lt;/span&gt;  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&amp;gt;; &lt;/span&gt;&lt;span class="err"&gt; 
&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;  
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&amp;gt; &lt;/span&gt;&lt;span class="err"&gt; 
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&amp;gt; &lt;/span&gt;&lt;span class="err"&gt; 
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt; &lt;/span&gt;&lt;span class="err"&gt; 
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;  

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;ProfileLoader&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyr8j6i03n8b1peu8x7e7.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyr8j6i03n8b1peu8x7e7.gif" alt="Image description" width="631" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Soporte —&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;finally()&lt;/code&gt; [&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally" rel="noopener noreferrer"&gt;ref&lt;/a&gt;] [&lt;a href="https://caniuse.com/promise-finally" rel="noopener noreferrer"&gt;ref&lt;/a&gt;]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;A considerar —&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  No devuelvas nuevos valores dentro de &lt;code&gt;.finally()&lt;/code&gt; ya que se se ignoran.&lt;/li&gt;
&lt;li&gt;  Usalo para tareas neutrales como limpiar loaders, cerrar conexiones, etc.&lt;/li&gt;
&lt;li&gt;  Evita lógica pesada en &lt;code&gt;.finally()&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rest</category>
      <category>spread</category>
      <category>finally</category>
      <category>asynchronousiteration</category>
    </item>
    <item>
      <title>Next.js - Fundamentos</title>
      <dc:creator>Mauricio Garcia</dc:creator>
      <pubDate>Fri, 16 May 2025 18:02:55 +0000</pubDate>
      <link>https://forem.com/mauriciogc/nextjs-fundamentos-35e2</link>
      <guid>https://forem.com/mauriciogc/nextjs-fundamentos-35e2</guid>
      <description>&lt;h2&gt;
  
  
  ¿Qué es Next.js?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Todos los ejemplos los podrás encontrar en el repositorio next.js-15.3–1[&lt;a href="https://github.com/mauriciogc/next.js-15.3-1" rel="noopener noreferrer"&gt;ref&lt;/a&gt;]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Next.js es un framework de React para crear aplicaciones web integrales. Se utilizan componentes de React para crear interfaces de usuario y Next.js para funciones y optimizaciones adicionales [ref].&lt;br&gt;
Entre sus principales características destacan:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sistema de rutas automático&lt;/strong&gt;: Utiliza la estructura de carpetas para generar rutas automáticamente, lo que elimina la necesidad de configurar un enrutador manualmente.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Renderizado híbrido&lt;/strong&gt;: Permite combinar distintos tipos de renderizado en una misma aplicación:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SSR&lt;/strong&gt; (Server-Side Rendering): Genera el HTML en cada solicitud.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSG&lt;/strong&gt; (Static Site Generation): Genera páginas estáticas en tiempo de
build.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSR&lt;/strong&gt; (Client-Side Rendering): Para secciones que se actualizan desde el cliente.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota&lt;/strong&gt;: Los tipos de renderización los vamos a revisar a fondo más adelante.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;API Routes integradas&lt;/strong&gt;: Puedes crear endpoints (backend) directamente dentro del proyecto, sin necesidad de un servidor externo. Esto te va a permitir manejar lógica de servidor como autenticación, conexión a bases de datos o procesamiento de formularios desde el mismo entorno de Next.js.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Optimización automática para SEO y rendimiento&lt;/strong&gt;: Soporte para metadatos, open graph y otros elementos importantes para SEO; optimización de imágenes y fuentes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;App Router moderno&lt;/strong&gt;: El nuevo sistema de rutas mejora la modularidad, permitiendo layouts anidados, manejo de errores por ruta y más, todo aprovechando las capacidades de React Server Components.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Soporte nativo para TypeScript, ESLint, Tailwind&lt;/strong&gt;, e integraciones modernas, facilitando un entorno de desarrollo robusto desde el inicio.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Crear un proyecto
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; Para poder configurar un nuevo proyecto en Next.js, asegurate de que tengas instalado Node.js +18.18 &lt;a href="https://nextjs.org/docs/app/getting-started/installation#system-requirements" rel="noopener noreferrer"&gt;[ref]&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Vamos a ejecutar en consola lo siguiente :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-next-app@latest my-project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Responde lo siguiente:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft38bsmx2ahqomynfml4w.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft38bsmx2ahqomynfml4w.webp" alt="Image description" width="800" height="286"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;TypeScript [yes]&lt;/strong&gt; -  Añade tipado estático a JS, lo que ayuda a detectar errores en tiempo de desarrollo. Mejora el autocompletado, navegación de código y documentación en editores modernos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ESLint [yes]&lt;/strong&gt; - Herramienta que analiza el código para encontrar errores y aplicar buenas prácticas automáticamente. Ayuda a mantener un código limpio, consistente y libre de errores comunes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tailwind CSS [yes]&lt;/strong&gt;  -  Framework de utilidades para CSS, permite construir interfaces modernas rápidamente. Altamente personalizable y escalable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;scr/ directory [yes]&lt;/strong&gt; -  Colocar el código dentro de la carpeta src/, permite tener una convención más clara y escalable. Ayuda a separar el código fuente del restro del proyecto (configuración, archivos estáticos, etc).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;App Router [yes]&lt;/strong&gt; -  Es el nuevo sistema de enrutamiento de Next.js (+v13) usando la carpeta /app. Permite tener Layouts anidados, React Server Components (RSC), loading/Error por ruta y mejor rendimiento.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Turbopack [yes]&lt;/strong&gt;  -  El nuevo bundler que tiene como objetivo reemplazar a Webpack. Mucho más rápido para el desarrollo y escalable (Aunque aún está en desarrollo, su integración con Next.js es prometedora y vale la pena probarlo, especialmente en nuevos proyectos.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Import alias [no]&lt;/strong&gt;  -  Cuando es un proyecto pequeño se puede dejar la opción No y agregarla más adelante cuando el proyecto crezca. Lo que hace es que evita tener imports largos y confusos, muchas veces los equipos prefieren configurar los alias manualmente en tsconfig.json para un mayor control.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Estructura del proyecto
&lt;/h3&gt;

&lt;p&gt;Nos genera una estructura como la siguiente &lt;a href="https://nextjs.org/docs/app/getting-started/project-structure" rel="noopener noreferrer"&gt;[ref]&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;Donde:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F81rpibz4vocz2fglr2sy.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F81rpibz4vocz2fglr2sy.webp" alt="Image description" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;public/&lt;/code&gt;  -  Carpeta donde colocas archivos estáticos accesibles directamente desde el navegador. (Ej. una imagen logo.png, será accesible desde &lt;code&gt;https://tusitio.com/logo.png&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;src/&lt;/code&gt;  -  Carpeta principal para organizar el código fuente.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;src/app/&lt;/code&gt;  -  Sistema basado en carpetas (App Router). Cada subcarpeta representa una ruta. Aqui se definen páginas, layouts, templates y componentes relacionados con las rutas.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;src/app/page.tsx&lt;/code&gt;  -  Archivo obligatorio que representa una página, en este caso la ruta raíz (/).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;src/app/layout.tsx&lt;/code&gt;  -  Define la estructura general que se aplica a la ruta y subrutas. Es como un App.tsx pero más estructurado. Útil para definir cabeceras, barras laterales, pies de página, etc.. Importante saber que se ejecuta del lado del servidor.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;src/app/globals.css&lt;/code&gt;  -  Archivo CSS global donde Tailwind importa sus estilos base. Aquí puedes agregar estilos globales personalizados.&lt;br&gt;
eslint.config.mjs - Configuración de ESLint, encargado de analizar el código estático.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;next-env.d.ts&lt;/code&gt;  -  Archivo generado automáticamente para que TypeScript entienda los tipos específicos de Next.js (No editar).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;next.config.ts &lt;/code&gt; -  Archivo de configuración de Next.js . Puedes modificar comportamientos globales (rutas personalizadas, redirecciones, headers, etc).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;postcss.config.mjs&lt;/code&gt;  -  Configuración para PostCSS, que Tailwind utiliza internamente para procesar CSS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;tsconfig.json &lt;/code&gt; -  Configuración de TypeScript. Define reglas de compilación, rutas, alias y compatibilidad del proyecto.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Actualiza la página principal
&lt;/h3&gt;

&lt;p&gt;Vamos a simplificar la página principal. Abre el archivo &lt;code&gt;src/app/page.tsx&lt;/code&gt; y sustituye el código generado, por el siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/app/page.tsx&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex justify-center items-center min-h-screen&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-3xl font-bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="err"&gt;¡&lt;/span&gt;&lt;span class="nx"&gt;Hola&lt;/span&gt; &lt;span class="nx"&gt;Mundo&lt;/span&gt; &lt;span class="nx"&gt;desde&lt;/span&gt; &lt;span class="nx"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;Tailwind&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/main&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Donde:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;export default function Home()&lt;/code&gt; — Es un componente como React, en este caso una página (&lt;code&gt;/&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Se usa Tailwind para estilos &lt;code&gt;items-center&lt;/code&gt;, &lt;code&gt;min-h-screen&lt;/code&gt;, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Al llamarse &lt;code&gt;page.tsx&lt;/code&gt;, Next.js hace una página automáticamente.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Descarga el proyecto actual [&lt;a href="https://github.com/mauriciogc/next.js-15.3-1/tree/base-project" rel="noopener noreferrer"&gt;ref&lt;/a&gt;] (branch: base-project)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Ejecutar el proyecto
&lt;/h3&gt;

&lt;p&gt;Para correr o ejecutar el proyecto &lt;a href="https://nextjs.org/docs/app/getting-started/installation#run-the-development-server" rel="noopener noreferrer"&gt;[ref]&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Abre en tu navegador:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;http://localhost:3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si todo está correcto, deberás ver lo siguiente:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkpupxrk9ygjn4td4r8ss.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkpupxrk9ygjn4td4r8ss.webp" alt="Image description" width="800" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota&lt;/strong&gt;: Cada vez que haces un cambio en un archivo, Next.js refrescará automáticamente el contenido.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>nextjs</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
