<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Santiago Toquica Yanguas - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Descubre miles de cursos de programación escritos por expertos. Aprende Desarrollo Web, Ciencia de Datos, DevOps, Seguridad y obtén asesoramiento profesional para desarrolladores. ]]>
        </description>
        <link>https://www.freecodecamp.org/espanol/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Santiago Toquica Yanguas - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/espanol/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 19 May 2026 20:02:09 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/espanol/news/author/toqyang/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Como centrar un Div con CSS ]]>
                </title>
                <description>
                    <![CDATA[ Hay algunos problemas comunes de codificación con los que te puedes encontrar cuando empieces a practicar lo que has aprendido construyendo proyectos. Un problema común al que te enfrentarás como desarrollador web es cómo colocar un elemento en el centro de una página o dentro de un elemento que actúa ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/como-centrar-un-div-con-css/</link>
                <guid isPermaLink="false">6535c5fca37ad203ea2a0afe</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Santiago Toquica Yanguas ]]>
                </dc:creator>
                <pubDate>Sun, 17 Dec 2023 18:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2023/12/pexels-pixabay-161043-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-center-a-div-with-css/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Center a Div with CSS</a>
      </p><h3 id="hay-algunos-problemas-comunes-de-codificaci-n-con-los-que-te-puedes-encontrar-cuando-empieces-a-practicar-lo-que-has-aprendido-construyendo-proyectos-">Hay algunos problemas comunes de codificación con los que te puedes encontrar cuando empieces a practicar lo que has aprendido construyendo proyectos.</h3><p>Un problema común al que te enfrentarás como desarrollador web es cómo colocar un elemento en el centro de una página o dentro de un elemento que actúa como su contenedor. Es el omnipresente problema de<em> "¿Cómo centro un div?"</em>.</p><p>En este artículo, veremos cómo podemos centrar elementos utilizando varias propiedades CSS. Veremos ejemplos de código en cada sección y una representación visual de los elementos en todos los ejemplos.</p><h2 id="c-mo-centrar-un-div-utilizando-la-propiedad-css-flexbox"><strong>Cómo centrar un Div utilizando la propiedad CSS Flexbox</strong></h2><p>En esta sección, veremos cómo podemos utilizar la propiedad Flexbox de CSS para centrar un elemento horizontalmente, verticalmente y en el centro de una página/contenedor.</p><p>Puedes usar una imagen si lo prefieres, pero nosotros usaremos un simple círculo dibujado con CSS. Aquí está el código:</p><figure class="kg-card kg-code-card"><pre><code class="language-html">&lt;div class="contenedor"&gt;

      &lt;div class="circulo"&gt;

      &lt;/div&gt;

&lt;/div&gt;</code></pre><figcaption>HTML contenedor inicial padre y circulo hijo</figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-css">.contenedor {
  width: 500px;
  height: 250px;
  margin: 50px;
  outline: solid 1px black;
}

.circulo {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background-color: black;
}</code></pre><figcaption>CSS inicial con clase contenedor y circulo</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2022/04/Screenshot--276-.png" class="kg-image" alt="Renderizado del círculo parte superior izquierda" width="600" height="400" loading="lazy"><figcaption>Círculo renderizado</figcaption></figure><p>El posicionamiento con Flexbox requiere que escribamos el código en la clase del elemento padre o contenedor.</p><h3 id="c-mo-centrar-un-div-horizontalmente-usando-flexbox"><strong>Cómo centrar un Div horizontalmente usando Flexbox</strong></h3><p>Ahora escribiremos el código para centrar el elemento div horizontalmente. Seguimos haciendo uso del círculo que creamos anteriormente.</p><figure class="kg-card kg-code-card"><pre><code class="language-css">.contenedor {
  width: 500px;
  height: 250px;
  margin: 50px;
  outline: solid 1px black;
  display: flex;
  justify-content: center;
}

.circulo {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background-color: black;
}</code></pre><figcaption>CSS inicial con clase contenedor y circulo</figcaption></figure><p>Hemos añadido dos líneas de código para centrar el círculo horizontalmente. Estas son las líneas que hemos añadido:</p><pre><code class="language-css">display: flex;
justify-content: center;</code></pre><p><code>display: flex;</code> nos permite utilizar Flexbox y sus propiedades.</p><p><code>justify-content: center;</code> alinea el círculo al centro horizontalmente.</p><p>Aquí está la posición de nuestro círculo:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2022/04/Screenshot--278-.png" class="kg-image" alt="Renderizado del círculo parte superior central" width="600" height="400" loading="lazy"><figcaption>Círculo centrado horizontalmente</figcaption></figure><h3 id="c-mo-centrar-un-div-verticalmente-usando-flexbox"><strong>Cómo centrar un Div verticalmente usando Flexbox</strong></h3><p>Lo que haremos en esta sección es similar a la anterior, excepto por una línea de código.</p><figure class="kg-card kg-code-card"><pre><code class="language-css">.contenedor {
  width: 500px;
  height: 250px;
  margin: 50px;
  outline: solid 1px black;
  display: flex;
  align-items: center;
}

.circulo {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background-color: black;
}</code></pre><figcaption>CSS inicial con clase contenedor y circulo</figcaption></figure><p>En este ejemplo, hemos utilizado <code>align-items: center;</code> para centrar el círculo verticalmente. Recuerda que debemos escribir primero <code>display: flex;</code> antes de especificar la dirección.</p><p>Aquí está la posición de nuestro círculo:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2022/04/Screenshot--280-.png" class="kg-image" alt="Renderizado del círculo parte central izquierda" width="600" height="400" loading="lazy"><figcaption>Círculo centrado verticalmente</figcaption></figure><h3 id="c-mo-posicionar-un-div-en-el-centro-usando-flexbox"><strong>Cómo posicionar un Div en el centro usando Flexbox</strong></h3><p>En esta sección, colocaremos el círculo en el centro de la página utilizando las propiedades de alineación horizontal y vertical de CSS Flexbox. He aquí cómo:</p><figure class="kg-card kg-code-card"><pre><code class="language-css">.contenedor {
  width: 500px;
  height: 250px;
  margin: 50px;
  outline: solid 1px black;
  display: flex;
  justify-content: center;
  align-items: center;
}

.circulo {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background-color: black;
}</code></pre><figcaption>CSS inicial con clase contenedor y circulo</figcaption></figure><p>Estas son las tres líneas de código que hemos añadido a la clase contenedor anterior:</p><figure class="kg-card kg-code-card"><pre><code class="language-css">display: flex;
justify-content: center;
align-items: center;</code></pre><figcaption>Centrado con propiedades de flexbox</figcaption></figure><p>Como es de esperar, comenzamos con <code>display: flex;</code> que nos permite utilizar Flexbox en CSS. A continuación, utilizamos las propiedades <code>justify-content</code> (alineación horizontal) y <code>align-items</code> (alineación vertical) para colocar el círculo en el centro de la página.</p><p>Esta es la posición de nuestro círculo:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2022/04/Screenshot--282-.png" class="kg-image" alt="Renderizado central en horizontal y vertical del plano" width="600" height="400" loading="lazy"><figcaption>Renderizado círculo</figcaption></figure><h2 id="c-mo-centrar-un-div-horizontalmente-usando-la-propiedad-margin-de-css"><strong>Cómo centrar un Div horizontalmente usando la propiedad</strong> <code>margin</code> <strong>de CSS</strong></h2><p>En esta sección, utilizaremos la propiedad <code>margin</code> para centrar nuestro círculo horizontalmente.</p><p>Volvamos a crear nuestro círculo.</p><figure class="kg-card kg-code-card"><pre><code class="language-html">&lt;div class="contenedor"&gt;

      &lt;div class="circulo"&gt;

      &lt;/div&gt;

&lt;/div&gt;</code></pre><figcaption>HTML inicial contenedor padre y circulo hijo</figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-css">.contenedor {
  width: 500px;
  height: 250px;
  margin: 50px;
  outline: solid 1px black;
}

.circulo {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background-color: black;
}</code></pre><figcaption>CSS inicial con clase contenedor y circulo</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2022/04/Screenshot--276-.png" class="kg-image" alt="Renderizado del círculo parte superior izquierda" width="600" height="400" loading="lazy"><figcaption>Renderizado círculo</figcaption></figure><p>Esta vez escribiremos el código en la clase <code>círculo</code>. He aquí cómo:</p><figure class="kg-card kg-code-card"><pre><code class="language-css">.contenedor {
  width: 500px;
  height: 250px;
  margin: 50px;
  outline: solid 1px black;
}

.circulo {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background-color: black;
  margin: 0 auto;
}</code></pre><figcaption>CSS inicial con clase contenedor y circulo</figcaption></figure><p>Todo lo que hemos añadido es el <code>margen: 0 auto;</code> línea de código a la clase <code>circulo</code>.</p><p>Echemos un vistazo a la posición del círculo:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2022/04/Screenshot--278--1.png" class="kg-image" alt="Renderizado del círculo parte superior central" width="600" height="400" loading="lazy"><figcaption>Renderizado círculo</figcaption></figure><h2 id="c-mo-centrar-texto-horizontalmente-con-la-propiedad-css-text-align"><strong>Cómo centrar texto horizontalmente con la propiedad CSS</strong> <code>text-align</code></h2><p>En esta sección, veremos cómo centrar texto horizontalmente.</p><p>Este método sólo funciona cuando trabajamos con texto escrito dentro de un elemento.</p><p>He aquí un ejemplo:</p><figure class="kg-card kg-code-card"><pre><code class="language-html">&lt;div class="contenedor"&gt;

    &lt;h1&gt;Hello World!&lt;/h1&gt;
      
&lt;/div&gt;</code></pre><figcaption>HTML inicial contenedor padre y h1 hijo</figcaption></figure><p>En el ejemplo anterior, hemos creado un <code>div</code> con una clase de contenedor y un elemento <code>h1</code> con algo de texto. Esto es lo que aparece en este momento:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2022/04/Screenshot--272-.png" class="kg-image" alt="Renderizado del texto parte superior izquierda" width="600" height="400" loading="lazy"><figcaption>Texto renderizado</figcaption></figure><p>Escribamos el código CSS.</p><figure class="kg-card kg-code-card"><pre><code class="language-css">.contenedor {
  width: 500px;
  height: 250px;
  margin: 50px;
  outline: solid 1px black;
}

h1 {
  text-align: center;
}</code></pre><figcaption>CSS inicial con clase contenedor y etiqueta h1</figcaption></figure><p>Para alinear el texto del elemento <code>h1</code> en el centro de la página, tuvimos que utilizar la propiedad <code>text-align</code>, dándole un valor de <code>center</code>. Esto es lo que aparece ahora en el navegador:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2022/04/Screenshot--274-.png" class="kg-image" alt="Renderizado del texto parte superior central" width="600" height="400" loading="lazy"><figcaption>Texto renderizado</figcaption></figure><h2 id="conclusi-n"><strong>Conclusión</strong></h2><p>En este artículo, vimos cómo podemos centrar elementos horizontalmente, verticalmente y en el centro de la página usando <strong>Flexbox</strong> y las propiedades <code>margin</code> y <code>text-align</code> en <strong>CSS</strong>.</p><p>En cada sección, vimos tanto un ejemplo de código como una representación visual de lo que hace el código.</p><p>¡Feliz codificación!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Manual de Next.js:  Aprender Next.js para principiantes ]]>
                </title>
                <description>
                    <![CDATA[ Escribí este tutorial para ayudarte a aprender rápidamente Next.js y familiarizarte con su funcionamiento. Es ideal para ti si tienes cero o poco conocimiento de Next.js, has usado React en el pasado y estás deseando sumergirte más en el ecosistema React, en particular en el renderizado del lado del servidor ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/manual-de-next-js/</link>
                <guid isPermaLink="false">64a2fb5213b6b807a602e5fc</guid>
                
                    <category>
                        <![CDATA[ NextJS ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Santiago Toquica Yanguas ]]>
                </dc:creator>
                <pubDate>Mon, 13 Nov 2023 14:53:06 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2023/08/Group-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/the-next-js-handbook/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">The Next.js Handbook – Learn Next.js for Beginners</a>
      </p><h3 id="escrib-este-tutorial-para-ayudarte-a-aprender-r-pidamente-next-js-y-familiarizarte-con-su-funcionamiento-">Escribí este tutorial para ayudarte a aprender rápidamente Next.js y familiarizarte con su funcionamiento.<br></h3><p>Es ideal para ti si tienes cero o poco conocimiento de Next.js, has usado React en el pasado y estás deseando sumergirte más en el ecosistema React, en particular en el renderizado del lado del servidor (<strong>server-side rendering</strong>).</p><p>Next.js me parece una herramienta impresionante para crear Aplicaciones Web, al final de este post espero que estés tan entusiasmado como yo. ¡Espero que te ayude a aprender Next.js!</p><p><a href="https://flaviocopes.com/page/nextjs-handbook/">Nota: puede descargar una versión PDF / ePub / Mobi de este tutorial para poder leerlo sin conexión.</a></p><h2 id="-ndice">Índice</h2><ol><li><a href="#intro">Introducción</a></li><li><a href="#principales">Principales características de Next.js</a></li><li><a href="#vs">Next.js vs Gatsby vs <code>create-react-app</code></a></li><li><a href="#instalar">Cómo instalar Next.js</a></li><li><a href="#ssr">Revisar código fuente para confirmar que SSR funciona</a></li><li><a href="#paquete">Los paquetes de aplicaciones</a></li><li><a href="#icono">¿Qué es ese icono en la parte inferior derecha?</a></li><li><a href="#devtools">Instalar React DevTools</a></li><li><a href="#otras">Otras técnicas de depuración que puedes utilizar</a></li><li><a href="#segunda">Añadir una segunda página al sitio web</a></li><li><a href="#dos">Enlazar las dos páginas</a></li><li><a href="#dinamico">Contenido dinámico con el router</a></li><li><a href="#previa">Prefetching(Búsqueda previa)</a></li><li><a href="#router">Uso del router para detectar el enlace activo</a></li><li><a href="#next-router">Uso de <code>next/router</code></a></li><li><a href="#getinitialprops">Alimentación de datos a los componentes mediante <code>getInitialProps()</code></a></li><li><a href="#css">CSS</a></li><li><a href="#tags">Rellenar la etiqueta head con etiquetas personalizadas</a></li><li><a href="#wrapper">Añadir un componente envolvente (Wrapper component)</a></li><li><a href="#api-routes">Rutas API</a></li><li><a href="#server">Ejecutar código en el lado del servidor o en el lado del cliente</a></li><li><a href="#despliegue">Despliegue de la versión de producción</a></li><li><a href="#now">Despliegue en Now</a></li><li><a href="#paquetes">Análisis de los paquetes de aplicaciones</a></li><li><a href="#carga">Módulos de carga lenta</a></li><li><a href="#ahora">Qué hacer a partir de ahora</a></li></ol><!--kg-card-begin: html--><h2 id="intro">Introducción</h2><!--kg-card-end: html--><p>Trabajar en una aplicación JavaScript moderna impulsada por React es increíble hasta que te das cuenta de que hay un par de problemas relacionados con la representación de todo el contenido en el lado del cliente.</p><p>En primer lugar, la página tarda más en ser visible para el usuario, porque antes de que se cargue el contenido, debe cargarse todo el JavaScript, y su aplicación necesita ejecutarse para determinar qué mostrar en la página.</p><p>En segundo lugar, si usted está construyendo un sitio web disponible al público, tiene un problema de SEO de contenido. Los motores de búsqueda están mejorando en la ejecución e indexación de aplicaciones JavaScript, pero es mucho mejor si podemos enviarles el contenido en lugar de dejar que ellos lo descubran.</p><p>La solución a ambos problemas es el <strong>renderizado del lado del servidor (server rendering</strong>), también llamado "<strong>pre-renderizado estático" </strong>(<strong>static pre-rendering</strong>).</p><p><a href="https://nextjs.org">Next.js </a> es un framework inspirado en React para hacer todo esto de una manera muy sencilla, pero no se limita a esto. Sus creadores lo anuncian como una cadena de <strong>herramientas de configuración cero y una</strong> <strong>interfaz de herramientas para aplicaciones en React.</strong></p><p>Proporciona una estructura común que te permite construir fácilmente un sitio web con React y maneja de forma transparente el renderizado del lado servidor <strong>(server-side rendering)</strong>.</p><!--kg-card-begin: html--><h2 id="principales">Principales características de Next.js</h2><!--kg-card-end: html--><p>He aquí una lista no exhaustiva de las principales características de Next.js:</p><h3 id="recarga-en-caliente-hot-code-reloading-">Recarga en caliente (Hot Code Reloading)</h3><p>Next.js recarga la página cuando detecta algún cambio guardado en disco.</p><h3 id="enrutamiento-autom-tico-automatic-routing-">Enrutamiento automático (Automatic Routing)</h3><p>Cualquier URL es mapeada al sistema de archivos, los cuales se ubican en la carpeta <code>pages</code>. No necesitas ninguna configuración (por supuesto, tienes opciones de personalización).</p><h3 id="componentes-de-un-solo-archivo-single-file-components-">Componentes de un solo archivo (Single File Components)</h3><p>Usando <code>styled-jsx</code>, completamente integrado y construido por el mismo equipo, es trivial añadir estilos al componente.</p><h3 id="renderizaci-n-del-lado-del-servidor-server-rendering-">Renderización del lado del servidor (Server Rendering)</h3><p>Puedes renderizar componentes React en el lado del servidor, antes de enviar el HTML al cliente.</p><h3 id="compatibilidad-con-el-ecosistema">Compatibilidad con el ecosistema</h3><p>Next.js funciona bien con el resto del ecosistema JavaScript, Node y React.</p><h3 id="separaci-n-autom-tica-del-c-digo">Separación automática del código</h3><p>Las páginas se renderizan sólo con las librerías y el JavaScript que requieren, nada más. En lugar de generar un único archivo JavaScript con todo el código de la aplicación, Next.js la divide automáticamente en varios recursos diferentes.</p><p>Al cargar una página sólo se carga el JavaScript necesario para esa página en concreto.</p><p>Next.js lo hace analizando los recursos importados.</p><p>Si sólo una de sus páginas importa la biblioteca Axios, por ejemplo, esa página específica incluirá la biblioteca en su paquete.</p><p>Esto garantiza que la carga de la primera página sea lo más rápida posible y que sólo las cargas de páginas futuras (si es que se activan) envíen el JavaScript necesario al cliente.</p><p>Hay una excepción notable. Las importaciones de uso frecuente se trasladan al paquete principal de JavaScript si se utilizan en al menos la mitad de las páginas del sitio.</p><h3 id="precarga-prefetching-">Precarga (Prefetching)</h3><p>El componente <code>Link</code>, utilizado para enlazar distintas páginas, admite una función de <code>prefetch</code> que precarga automáticamente los recursos de la página (incluido el código que falta debido a la separación del código) en segundo plano.</p><h3 id="componentes-din-micos-dynamic-components-">Componentes dinámicos (Dynamic Components)</h3><p>Puedes importar módulos JavaScript y componentes React de forma dinámica.</p><h3 id="exportaci-n-est-tica-static-exports-">Exportación estática (Static Exports)</h3><p>Usando el comando <code>next export</code>, Next.js te permite exportar un sitio completamente estático de tu aplicación.</p><h3 id="compatibilidad-con-typescript">Compatibilidad con TypeScript</h3><p>Next.js está escrito en TypeScript y como tal viene con un excelente soporte para TypeScript.</p><!--kg-card-begin: html--><h2 id="vs">Next.js vs Gatsby vs <code>create-react-app</code></h2><!--kg-card-end: html--><p>Next.js, <a href="https://flaviocopes.com/gatsby/">Gatsby</a> y <code>create-react-app</code> son herramientas increíbles que podemos utilizar para potenciar nuestras aplicaciones.</p><p>Digamos primero lo que tienen en común. Todas tienen React bajo el capó, potenciando toda la experiencia de desarrollo. También abstraen <a href="https://flaviocopes.com/webpack/">webpack</a> y todas esas cosas de bajo nivel que solíamos configurar manualmente en los viejos tiempos.</p><p><code>create-react-app</code> no te ayuda a generar una aplicación renderizada del lado del servidor fácilmente. Todo lo que viene con ello (SEO, velocidad...) sólo lo proporcionan herramientas como Next.js y Gatsby.</p><p><strong>¿Cuándo es Next.js mejor que Gatsby?</strong></p><p>Ambos pueden ayudar con el renderizado del lado del servidor &nbsp;(<strong>server-side rendering</strong>), pero de 2 maneras diferentes.</p><p>El resultado final usando Gatsby es un generador de sitios estáticos, sin servidor. Usted construye el sitio, y luego despliega el resultado del proceso de construcción estáticamente en Netlify u otro sitio de alojamiento estático.</p><p>Next.js proporciona un backend que puede renderizar del lado del servidor una respuesta a la petición, lo que permite crear un sitio web dinámico, lo que significa que se desplegará en una plataforma que pueda ejecutar Node.js.</p><p>Next.js también puede generar un sitio estático, pero yo no diría que es su principal caso de uso.</p><p>Si mi objetivo fuera construir un sitio estático, me costaría elegir y quizás Gatsby tenga un mejor ecosistema de plugins, incluyendo muchos para blogging en particular.</p><p>Gatsby también se basa en gran medida en <a href="https://graphql.org/">GraphQL</a>, algo que puede gustarte o disgustarte dependiendo de tus opiniones y necesidades.</p><!--kg-card-begin: html--><h2 id="instalar">¿Cómo instalar Next.js?</h2><!--kg-card-end: html--><p>Para instalar Next.js, necesitas tener instalado Node.js.</p><p>Asegúrate de que tienes la última versión de Node. Compruébalo ejecutando <code>node -v</code> en tu terminal y compárala con la última versión LTS listada en <a href="https://nodejs.org/">https://nodejs.org/</a>.</p><p>Después de instalar Node.js, tendrás el comando <code>npm</code> disponible en tu línea de comandos.</p><p>Si tienes algún problema en esta 1 fase, te recomiendo los siguientes tutoriales que he escrito para ti:</p><ul><li><a href="https://flaviocopes.com/node-installation/">Cómo instalar Node.js</a></li><li><a href="https://flaviocopes.com/how-to-update-node/">Cómo actualizar Node.js</a></li><li><a href="https://flaviocopes.com/npm/">Introducción al gestor de paquetes npm</a></li><li><a href="https://flaviocopes.com/node-installation/">Tutorial de Unix Shell</a></li><li><a href="https://flaviocopes.com/macos-terminal/">Cómo usar el terminal de macOS</a></li><li><a href="https://flaviocopes.com/bash/">El intérprete de comandos Bash</a></li></ul><p>Ahora que tienes Node actualizado a la última versión y <code>npm</code>, ¡estamos listos!</p><p>Ahora podemos elegir 2 rutas: usar <code>create-next-app</code> o el enfoque clásico que implica instalar y configurar una aplicación Next manualmente.</p><h3 id="usando-create-next-app">Usando create-next-app</h3><p>Si estás familiarizado con <code>create-react-app</code>, &nbsp;<code>create-next-app</code> es lo mismo - excepto que crea una aplicación Next en lugar de una aplicación React, como su nombre indica.</p><p>Supongo que ya tienes instalado Node.js, desde la versión 5.2 (hace más de 2 años en el momento de escribir esto), viene con el<a href="https://flaviocopes.com/npx/"> comando <code>npx</code></a> incluido. Esta herramienta útil nos permite descargar y ejecutar un comando JavaScript y lo usaremos así:</p><pre><code class="language-bash">npx create-next-app
</code></pre><p>El comando pregunta el nombre de la aplicación (y crea una nueva carpeta para ti con ese nombre), luego descarga todos los paquetes que necesita ( <code>react</code>, <code>react-dom</code>, <code>next</code>), establece el <code>package.json</code> a:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-14-at-16.46.47.png" class="kg-image" alt="package.json" width="600" height="400" loading="lazy"><figcaption>package.json</figcaption></figure><p>y puedes ejecutar inmediatamente la aplicación de ejemplo ejecutando <code>npm run dev</code>:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-14-at-16.46.32.png" class="kg-image" alt="Inicio de ejecución Next js" width="600" height="400" loading="lazy"><figcaption>Inicio de ejecución Next js</figcaption></figure><p>Y aquí está el resultado en <a href="http://localhost:3000">http://localhost:3000</a>:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-14-at-16.47.17.png" class="kg-image" alt="Aplicación iniciada en el navegador" width="600" height="400" loading="lazy"><figcaption>Aplicación iniciada en el navegador</figcaption></figure><p>Esta es la forma recomendada de iniciar una aplicación Next.js, ya que te proporciona estructura y código de ejemplo con el que jugar. Hay más ejemplos aparte del predeterminado; puedes usar cualquiera de los ejemplos almacenados en <a href="https://github.com/zeit/next.js/tree/canary/examples">https://github.com/zeit/next.js/tree/canary/examples</a> usando la opción <code>--example</code>. Por ejemplo, prueba:</p><pre><code class="language-bash">npx create-next-app --example blog-starter
</code></pre><p>Lo que le da una instancia de blog inmediatamente utilizable con resaltado de sintaxis también:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-14-at-17.13.29.png" class="kg-image" alt="Aplicación de ejemplo blog" width="600" height="400" loading="lazy"><figcaption>Aplicación de ejemplo blog</figcaption></figure><h3 id="crear-manualmente-una-aplicaci-n-next-js">Crear manualmente una aplicación Next.js</h3><p>Puedes evitar <code>create-next-app</code> si te apetece crear una aplicación Next desde cero. He aquí cómo: crea una carpeta vacía donde quieras, por ejemplo en tu carpeta de inicio y entra en ella:</p><pre><code class="language-sh">mkdir nextjs
cd nextjs
</code></pre><p>y crea tu primer directorio del proyecto Next:</p><pre><code class="language-sh">mkdir firstproject
cd firstproject
</code></pre><p>Ahora usa el comando <code>npm</code> para inicializarlo como un proyecto Node:</p><pre><code class="language-sh">npm init -y
</code></pre><p>La opción <code>-y</code> indica a <code>npm</code> que utilice la configuración predeterminada para un proyecto, rellenando un archivo <code>package.json</code> de ejemplo.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-16.59.21.png" class="kg-image" alt="Inicializando proyecto con npm init -y" width="600" height="400" loading="lazy"><figcaption>Inicializando proyecto con npm init -y</figcaption></figure><p>Ahora instala Next y React:</p><pre><code class="language-sh">npm install next react react-dom
</code></pre><p>Su carpeta de proyecto debe tener ahora 2 archivos:</p><ul><li><code>package.json</code> (<a href="https://flaviocopes.com/package-json/">ver mi tutorial sobre ello</a>)</li><li><code>package-lock.json</code> (<a href="https://flaviocopes.com/package-lock-json/">ver mi tutorial sobre package-lock</a>)</li></ul><p>y la carpeta <code>node_modules</code>.</p><p>Abra la carpeta del proyecto utilizando su editor favorito. Mi editor favorito es <a href="https://flaviocopes.com/vscode/">VS Code</a>. Si lo tienes instalado, puedes ejecutar <code>code .</code> en tu terminal para abrir la carpeta actual en el editor (si el comando no te funciona, mira esto)</p><p>Abra <code>package.json</code>, que ahora tiene este contenido:</p><pre><code class="language-json">{
  "name": "firstproject",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" &amp;&amp; exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies":  {
    "next": "^9.1.2",
    "react": "^16.11.0",
    "react-dom": "^16.11.0"
  }
}
</code></pre><p>y reemplazar la sección de <code>scripts</code> con:</p><pre><code class="language-json">"scripts": {
  "dev": "next",
  "build": "next build",
  "start": "next start"
}
</code></pre><p>Para añadir los comandos de compilación de Next.js, que usaremos pronto.</p><p>Consejo: usa <code>"dev": "next -p 3001"</code>, para cambiar el puerto y ejecutar, en este ejemplo, en el puerto 3001.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-17.01.03.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-17.01.03" width="600" height="400" loading="lazy"></figure><p>Ahora crea una carpeta <code>pages</code> y añade un archivo <code>index.js</code>.</p><p>En este archivo, vamos a crear nuestro primer componente React.</p><p>Vamos a utilizarlo como la exportación por defecto:</p><pre><code class="language-js">const Index = () =&gt; (
  &lt;div&gt;
    &lt;h1&gt;Home page&lt;/h1&gt;
  &lt;/div&gt;
)

export default Index
</code></pre><p>Ahora, usando el terminal, ejecuta <code>npm run dev</code> para iniciar el servidor de desarrollo Next.</p><p>Esto hará que la aplicación esté disponible en el puerto 3000, en localhost.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-11.24.02.png" class="kg-image" alt="Ejecución del proyecto con npm run dev" width="600" height="400" loading="lazy"><figcaption>Ejecución del proyecto con npm run dev</figcaption></figure><p>Abra <a href="http://localhost:3000">http://localhost:3000</a> en su navegador para verlo.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-11.24.23.png" class="kg-image" alt="Componente con el texto Home page" width="600" height="400" loading="lazy"><figcaption>Componente con el texto Home page</figcaption></figure><!--kg-card-begin: html--><h2 id="ssr">Ver código fuente para confirmar que  <em>(Renderizado del lado del servidor)</em> SSR está trabajando</h2><!--kg-card-end: html--><p>Comprobemos ahora que la aplicación funciona como esperamos. Es una aplicación Next.js, por lo que debería renderizarse del lado del servidor (<strong>server side rendered</strong>).</p><p>Es uno de los principales argumentos de venta de Next.js: si creamos un sitio utilizando Next.js, las páginas del sitio se renderizan en el servidor, que entrega HTML al navegador.</p><p>Esto tiene 3 ventajas principales:</p><ul><li>El cliente no necesita instanciar React para renderizar, lo que hace que el sitio sea más rápido para sus usuarios.</li><li>Los motores de búsqueda indexarán las páginas sin necesidad de ejecutar el JavaScript del lado del cliente. Algo que Google comenzó a hacer, pero admitió abiertamente que es un proceso más lento (y debes ayudar a Google tanto como sea posible, si quieres clasificar bien).</li><li>Puede tener metaetiquetas de medios sociales, útiles para añadir imágenes de vista previa, personalizar el título y la descripción de cualquiera de sus páginas compartidas en Facebook, Twitter, etc.</li></ul><p>Vamos a ver la fuente de la aplicación. </p><p>Usando Chrome puede hacer clic derecho en cualquier lugar de la página, y pulse Ver fuente de la página(<strong>View Page Source</strong>).</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-11.33.10.png" class="kg-image" alt="Código fuente construido" width="600" height="400" loading="lazy"><figcaption>Código fuente construido</figcaption></figure><p>Si ves el código fuente de la página, verás el fragmento <code>&lt;div&gt;&lt;h1&gt;Home page&lt;/h1&gt;&lt;/div&gt;</code> en el <code>body</code> del HTML, junto con un montón de archivos JavaScript: los paquetes de la aplicación.</p><p>No necesitamos configurar nada, <strong>SSR</strong> (Renderizado del lado del servidor) ya está trabajando para nosotros.</p><p><br>La aplicación React se ejecutará en el cliente y será el que ejecute las interacciones como hacer clic en un enlace, utilizando la renderización del lado del cliente. Pero al recargar una página se volverá a cargar desde el servidor. Y usando Next.js no debería haber ninguna diferencia en el resultado dentro del navegador - una página renderizada desde el servidor debería verse exactamente igual que una página renderizada desde el cliente.</p><!--kg-card-begin: html--><h2 id="paquete">Paquete de aplicación (app bundle)</h2><!--kg-card-end: html--><p>Cuando revisamos el código fuente de la página, vimos que se estaban cargando un montón de archivos JavaScript:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-11.34.41.png" class="kg-image" alt="Scripts cargando en el código fuente" width="600" height="400" loading="lazy"><figcaption>Scripts cargando en el código fuente</figcaption></figure><p>Empecemos por poner el código en un <a href="https://htmlformatter.com/">formateador HTML</a> para formatearlo mejor de modo que los humanos tengamos más posibilidades de entenderlo:</p><figure class="kg-card kg-code-card"><pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html&gt;

&lt;head&gt;
    &lt;meta charSet="utf-8" /&gt;
    &lt;meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1" /&gt;
    &lt;meta name="next-head-count" content="2" /&gt;
    &lt;link rel="preload" href="/_next/static/development/pages/index.js?ts=1572863116051" as="script" /&gt;
    &lt;link rel="preload" href="/_next/static/development/pages/_app.js?ts=1572863116051" as="script" /&gt;
    &lt;link rel="preload" href="/_next/static/runtime/webpack.js?ts=1572863116051" as="script" /&gt;
    &lt;link rel="preload" href="/_next/static/runtime/main.js?ts=1572863116051" as="script" /&gt;
&lt;/head&gt;

&lt;body&gt;
    &lt;div id="__next"&gt;
        &lt;div&gt;
            &lt;h1&gt;Home page&lt;/h1&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;script src="/_next/static/development/dll/dll_01ec57fc9b90d43b98a8.js?ts=1572863116051"&gt;&lt;/script&gt;
    &lt;script id="__NEXT_DATA__" type="application/json"&gt;{"dataManager":"[]","props":{"pageProps":{}},"page":"/","query":{},"buildId":"development","nextExport":true,"autoExport":true}&lt;/script&gt;
    &lt;script async="" data-next-page="/" src="/_next/static/development/pages/index.js?ts=1572863116051"&gt;&lt;/script&gt;
    &lt;script async="" data-next-page="/_app" src="/_next/static/development/pages/_app.js?ts=1572863116051"&gt;&lt;/script&gt;
    &lt;script src="/_next/static/runtime/webpack.js?ts=1572863116051" async=""&gt;&lt;/script&gt;
    &lt;script src="/_next/static/runtime/main.js?ts=1572863116051" async=""&gt;&lt;/script&gt;
&lt;/body&gt;

&lt;/html&gt;
</code></pre><figcaption>Página principal construida</figcaption></figure><p>Tenemos 4 archivos JavaScript declarados para ser precargados en la etiqueta <code>head</code>, usando <code>rel="preload" as="script"</code>:</p><ul><li><code>/_next/static/development/pages/index.js</code> (96 LOC)</li><li><code>/_next/static/development/pages/_app.js</code> (5900 LOC)</li><li><code>/_next/static/runtime/webpack.js</code> (939 LOC)</li><li><code>/_next/static/runtime/main.js</code> (12k LOC)</li></ul><p>Esto indica al navegador que empiece a cargar esos archivos lo antes posible, antes de que comience el flujo normal de renderizado. Sin ellos, los scripts se cargarían con un retraso adicional, esto mejora el rendimiento de carga de la página.</p><p>Entonces esos 4 archivos se cargan al final del <code>body</code>, junto con <code>/_next/static/development/dll/dll_01ec57fc9b90d43b98a8.js</code> (31k LOC), y un fragmento JSON que establece algunos valores por defecto para los datos de la página:</p><figure class="kg-card kg-code-card"><pre><code class="language-html">&lt;script id="__NEXT_DATA__" type="application/json"&gt;
{
  "dataManager": "[]",
  "props": {
    "pageProps":  {}
  },
  "page": "/",
  "query": {},
  "buildId": "development",
  "nextExport": true,
  "autoExport": true
}
&lt;/script&gt;
</code></pre><figcaption>Script de Next Js</figcaption></figure><p>Los 4 archivos bundle ya cargados, están implementando una característica llamada división de código. El archivo <code>index.js</code> proporciona el código necesario para el componente <code>index</code>, que sirve a la ruta <code>/</code>, si tuviéramos más páginas tendríamos más paquetes para cada página, que sólo se cargarán si es necesario - para proporcionar un tiempo de carga más eficiente para la página.</p><!--kg-card-begin: html--><h2 id="icono">¿Qué es ese icono de abajo a la derecha?</h2><!--kg-card-end: html--><p>¿Has visto ese pequeño icono en la parte inferior derecha de la página, que parece un rayo?</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-13.21.42.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-13.21.42" width="600" height="400" loading="lazy"></figure><p>Si pasas el ratón por encima, dirá "Página prerrenderizada":</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-13.21.46.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-13.21.46" width="600" height="400" loading="lazy"></figure><p>Este icono, que <em>sólo es visible en el modo de desarrollo</em>, por supuesto, le dice que la página califica para la optimización estática automática, lo que básicamente significa que no depende de los datos que deben obtenerse en el momento de la invocación y puede ser prerenderizada y construida como un archivo HTML estático en tiempo de compilación (cuando ejecutamos <code>npm run build</code>).</p><p>A continuación podemos determinar esto por la ausencia del método <code>getInitialProps()</code> adjunto al componente de página.</p><p>Cuando este es el caso, nuestra página puede ser aún más rápida porque se servirá estáticamente como un archivo HTML en lugar de pasar por el servidor Node.js que genera la salida HTML.</p><p>Otro icono útil que puede aparecer junto a él o en lugar de él en páginas no pre-renderizadas, es un pequeño triángulo animado:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-14-at-14.56.21.png" class="kg-image" alt="Screen-Shot-2019-11-14-at-14.56.21" width="600" height="400" loading="lazy"></figure><p>Este es un indicador de compilación, aparece cuando guardas una página y Next.js está compilando la aplicación antes de que la recarga de código en caliente (hot code reloading) se active para recargar el código en la aplicación automáticamente.</p><p>Es una forma muy agradable de determinar inmediatamente si la aplicación ya ha sido compilada y puedas probar la parte en la que estás trabajando.</p><!--kg-card-begin: html--><h2 id="devtools">Instalar React Developer Tools</h2>
<!--kg-card-end: html--><p>Next.js se basa en React, por lo que una herramienta muy útil que es absolutamente necesario instalar (si aún no lo ha hecho) es React Developer Tools.</p><p>Disponible tanto para <a href="https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en">Chrome</a> como para <a href="https://addons.mozilla.org/en-US/firefox/addon/react-devtools/">Firefox</a>, las React Developer Tools son un instrumento esencial que puedes utilizar para inspeccionar una aplicación React.</p><p>Ahora, las React Developer Tools no son específicas de Next.js pero quiero presentarlas porque puede que no estés 100% familiarizado con todas las herramientas que React proporciona. Es mejor adentrarse un poco en las herramientas de depuración que asumir que ya las conoces.</p><p>Estas proporcionan un inspector que revela el árbol de componentes de React que construye tu página y para cada componente puedes ir a comprobar los props, el estado, hooks y mucho más.</p><p>Una vez que hayas instalado las React Developer Tools, puedes abrir las devtools del navegador normal (en Chrome, es hacer clic con el botón derecho en la página, y luego hacer clic en <code>Inspect</code>) y encontrarás 2 nuevos paneles: <strong>Components</strong> y <strong>Profiler</strong>.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-14.26.12.png" class="kg-image" alt="React Developer Tools" width="600" height="400" loading="lazy"><figcaption>React Developer Tools</figcaption></figure><p>Si mueves el ratón sobre los componentes, verás que en la página, el navegador seleccionará las partes que son renderizadas por ese componente.</p><p>Si seleccionas cualquier componente en el árbol, el panel derecho te mostrará una referencia al <strong>componente padre</strong> y los props pasados a él:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-14.27.05.png" class="kg-image" alt="Componente Index en React Developer Tools" width="600" height="400" loading="lazy"><figcaption>Componente Index en React Developer Tools</figcaption></figure><p>Puedes navegar fácilmente haciendo clic alrededor de los nombres de los componentes.</p><p>Puedes hacer clic en el icono del ojo en la barra de herramientas de desarrollador para inspeccionar el elemento DOM, también si utilizas el primer icono, el del ratón (que convenientemente se encuentra debajo del similar icono DevTools regular), puedes pasar por un elemento en la interfaz de usuario del navegador para seleccionar directamente el componente React que lo renderiza.<br></p><p>Puedes usar el icono del error <strong>(bug)</strong> para registrar los datos de un componente en la consola.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-14.31.25.png" class="kg-image" alt="Componentes en la consola" width="600" height="400" loading="lazy"><figcaption>Componentes en la consola</figcaption></figure><p>Esto es bastante impresionante porque una vez que tienes los datos impresos allí, puedes hacer clic derecho en cualquier elemento y pulsar "Almacenar como variable global". Por ejemplo aquí lo hice con la prop <code>url</code> pude inspeccionarla en la consola usando la variable temporal que se le asignó <code>temp1</code>:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-14.40.22.png" class="kg-image" alt="Variables globales" width="600" height="400" loading="lazy"><figcaption>Variables globales</figcaption></figure><p>Usando <strong>Source Maps</strong>, que son cargados por Next.js automáticamente en modo desarrollo, desde el panel Componentes podemos pulsar el código <code>&lt;&gt;</code> y el DevTools cambiará al panel Fuente, mostrándonos el código fuente del componente:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-14.41.33.png" class="kg-image" alt="Componente Index en tab source del navegador" width="600" height="400" loading="lazy"><figcaption>Componente Index en tab source del navegador</figcaption></figure><p>La pestaña <strong>Profiler</strong> es aún más impresionante, si cabe. Nos permite <strong>grabar una interacción</strong> en la app para ver qué ocurre. No puedo mostrar un ejemplo todavía, porque se necesitan al menos 2 componentes para crear una interacción, y ahora sólo tenemos uno. Hablaré de esto más adelante.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-14.42.24.png" class="kg-image" alt="React Dev Tools - Profiler" width="600" height="400" loading="lazy"><figcaption>React Dev Tools - Profiler</figcaption></figure><p>He mostrado todas las capturas de pantalla usando Chrome, pero React Developer Tools funciona de la misma manera en Firefox:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-14.45.20.png" class="kg-image" alt="React Dev Tools - Firefox" width="600" height="400" loading="lazy"><figcaption>React Dev Tools - Firefox</figcaption></figure><!--kg-card-begin: html--><h2 id="otras">Otras técnicas de depuración que puede utilizar</h2><!--kg-card-end: html--><p>Además de las React Developer Tools, que son esenciales para construir una aplicación Next.js, quiero hacer hincapié en 2 formas de depurar aplicaciones en Next.js.</p><p>La primera es obviamente <code>console.log()</code> y todas las <a href="https://flaviocopes.com/console-api/">demás herramientas de la API de Consola</a>. La forma en que funcionan las aplicaciones Next hará que una declaración de tipo log funcione en la consola del navegador o en la terminal donde iniciaste Next usando <code>npm run dev</code>.</p><p>En particular, si la página se carga desde el servidor, cuando apuntas la URL a ella, o pulsas el botón refrescar / cmd/ctrl-R, cualquier registro de consola ocurre en la terminal.</p><p>Las subsiguientes transiciones de página que ocurran al pulsar el ratón harán que todo el registro de consola ocurra dentro del navegador.</p><p>Sólo recuerde si usted se sorprende por la falta de registro de mensajes.</p><p>Otra herramienta que es esencial es la palabra <code>debugger</code>. Añadiendo esta sentencia a un componente se pausará el renderizado de la página por parte del navegador:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-15.10.32.png" class="kg-image" alt="debugger en componente Index" width="600" height="400" loading="lazy"><figcaption>debugger en componente Index</figcaption></figure><p>Realmente impresionante porque ahora puedes usar el depurador del navegador para inspeccionar valores y ejecutar tu aplicación línea a línea.</p><p>También puedes usar el depurador de VS Code para depurar código del lado del servidor. Menciono esta técnica y <a href="https://github.com/Microsoft/vscode-recipes/tree/master/Next-js">este tutorial</a> para configurar esto.</p><!--kg-card-begin: html--><h2 id="segunda">Añadir una segunda página al sitio web</h2><!--kg-card-end: html--><p>Ahora que tenemos un buen conocimiento de las herramientas que podemos utilizar para ayudarnos a desarrollar aplicaciones Next.js, vamos a continuar desde donde dejamos nuestra primera aplicación:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-13.21.42-1.png" class="kg-image" alt="Localhost en Firefox" width="600" height="400" loading="lazy"><figcaption>Localhost en Firefox</figcaption></figure><p>Quiero añadir una segunda página a este sitio web, un blog. Va a ser servido en <code>/blog</code> y por el momento sólo contendrá una simple página estática, al igual que nuestro primer componente <code>index.js</code>:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-15.39.40.png" class="kg-image" alt="Componente Blog" width="600" height="400" loading="lazy"><figcaption>Componente Blog</figcaption></figure><p>Después de guardar el nuevo archivo, el proceso <code>npm run dev</code> ya en ejecución es capaz de renderizar la página, sin necesidad de reiniciarlo.<br></p><p>Cuando pulsamos la URL <a href="http://localhost:3000/blog">http://localhost:3000/blog</a> tenemos la nueva página:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-15.41.39.png" class="kg-image" alt="Ruta con componente Blog" width="600" height="400" loading="lazy"><figcaption>Ruta con componente Blog</figcaption></figure><p>y esto es lo que nos dijo el terminal:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-15.41.03.png" class="kg-image" alt="Terminal con estado exitoso" width="600" height="400" loading="lazy"><figcaption>Terminal con estado exitoso</figcaption></figure><p>Ahora el hecho de que la URL sea <code>/blog</code> depende sólo del nombre del archivo y de su posición dentro de la carpeta <code>pages</code>.</p><p>Puedes crear una página <code>pages/hey/ho</code> y esta página aparecerá en la URL <a href="http://localhost:3000/hey/ho">http://localhost:3000/hey/ho</a>.</p><p>Lo que no importa, a efectos de la URL, es el nombre del componente dentro del archivo.</p><p>Intenta ir y ver el código fuente de la página, cuando se carga desde el servidor listará <code>/_next/static/development/pages/blog.js</code> como uno de los paquetes cargados y no <code>/_next/static/development/pages/index.js</code> como en la página de inicio. Esto se debe a que gracias a la división automática del código no necesitamos el bundle que sirve a la página de inicio. Sólo el paquete de aplicación<strong>(bundle)</strong> que sirve la página del blog.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-16.24.53.png" class="kg-image" alt="Código fuente de ruta /blog" width="600" height="400" loading="lazy"><figcaption>Código fuente de ruta /blog</figcaption></figure><p>También podemos simplemente exportar una función anónima desde <code>blog.js</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">export default () =&gt; (
  &lt;div&gt;
    &lt;h1&gt;Blog&lt;/h1&gt;
  &lt;/div&gt;
)
</code></pre><figcaption>Componente Blog con función anónima de flecha</figcaption></figure><p>o si prefiere la sintaxis de funciones sin flechas:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">export default function() {
  return (
    &lt;div&gt;
      &lt;h1&gt;Blog&lt;/h1&gt;
    &lt;/div&gt;
  )
}
</code></pre><figcaption>Componente Blog sin función flecha</figcaption></figure><!--kg-card-begin: html--><h2 id="dos">Enlazar las dos páginas</h2>
<!--kg-card-end: html--><p>Ahora que tenemos 2 páginas, definidas por <code>index.js</code> y <code>blog.js</code>, podemos introducir enlaces.</p><p>Los enlaces HTML normales dentro de las páginas se hacen utilizando la etiqueta <code>a</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-html">&lt;a href="/blog"&gt;Blog&lt;/a&gt;
</code></pre><figcaption>Etiqueta "a" (Hipervinculos)</figcaption></figure><p>No podemos hacer eso en Next.js.</p><p>¿Por qué? Técnicamente podemos, claro, porque esto es la Web y en la Web las cosas nunca se rompen (por eso podemos seguir usando la etiqueta <code>&lt;marquee&gt;</code>. Pero una de las principales ventajas de usar Next, es que una vez cargada una página, las transiciones a otra son muy rápidas gracias al renderizado del lado del cliente.</p><p>Si usas un simple enlace <code>a</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">const Index = () =&gt; (
  &lt;div&gt;
    &lt;h1&gt;Home page&lt;/h1&gt;
    &lt;a href='/blog'&gt;Blog&lt;/a&gt;
  &lt;/div&gt;
)

export default Index
</code></pre><figcaption>Componente Index con etiqueta a</figcaption></figure><p>Ahora abre el <strong>DevTools</strong>, y el panel de <strong>Network panel </strong>(Panel Red). La primera vez que cargamos <a href="http://localhost:3000/">http://localhost:3000/</a> se cargan todos los paquetes de páginas:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-16.26.00.png" class="kg-image" alt="Network tab" width="600" height="400" loading="lazy"><figcaption>Network tab</figcaption></figure><p>Ahora, si haces clic en el botón "Conservar registro" (para evitar que se borre el panel Red), haces clic en el enlace "Blog", esto es lo que ocurre:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-16.27.16.png" class="kg-image" alt="Network tab cargando código" width="600" height="400" loading="lazy"><figcaption>Network tab cargando código</figcaption></figure><p>Tenemos todo ese JavaScript del servidor, ¡otra vez! Pero... no necesitamos todo ese JavaScript si ya lo tenemos. Sólo necesitaríamos el paquete de página <code>blog.js</code>, el único que es nuevo en la página.</p><p>Para solucionar este problema, utilizamos un componente proporcionado por Next, llamado <strong>Link</strong>.</p><p>Lo importamos:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">import Link from 'next/link'
</code></pre><figcaption>Componente Link en Next Js</figcaption></figure><p>y luego lo usamos para envolver nuestro enlace, así:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">import Link from 'next/link'

const Index = () =&gt; (
  &lt;div&gt;
    &lt;h1&gt;Home page&lt;/h1&gt;
    &lt;Link href='/blog'&gt;
      &lt;a&gt;Blog&lt;/a&gt;
    &lt;/Link&gt;
  &lt;/div&gt;
)

export default Index
</code></pre><figcaption>Componente Link envolviendo etiqueta a</figcaption></figure><p>Ahora si vuelves a intentar lo que hicimos anteriormente, podrás ver que sólo se carga el bundle <code>blog.js</code> cuando pasamos a la página del blog:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-16.35.18.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-16.35.18" width="600" height="400" loading="lazy"></figure><p>y la página se cargó tan rápido que ni siquiera apareció el spinner habitual del navegador en la pestaña. Sin embargo, la URL cambió, como puedes ver. Esto funciona perfectamente con la <a href="https://flaviocopes.com/history-api/">API del historial del navegador</a>.</p><p>Esto es renderizado del lado del cliente en acción.</p><p>¿Y si ahora pulsas el botón Atrás? No se descarga nada, porque el navegador todavía tiene el antiguo paquete <code>index.js</code>, listo para cargar la ruta <code>/index</code>. Todo es automático.</p><!--kg-card-begin: html--><h2 id="dinamico">Contenido dinámico con el router</h2><!--kg-card-end: html--><p>En el capítulo anterior vimos cómo enlazar la página home con la página del blog.</p><p>Un blog es un gran caso de uso para Next.js, que seguiremos explorando en este capítulo añadiendo más <strong>artículos al blog</strong>.</p><p>Los artículos de blog tienen una URL dinámica. Por ejemplo, una entrada titulada "Hello World" podría tener la URL <code>/blog/hello-world</code>. Una entrada titulada "My second post" podría tener la URL <code>/blog/my-second-post</code>.</p><p>Este contenido es dinámico y puede proceder de una base de datos, archivos markdown u otros.</p><p>Next.js puede servir contenido dinámico basado en una <strong>URL dinámica</strong>.</p><p>Creamos una URL dinámica creando una página dinámica con la sintaxis <code>[]</code>.</p><p>¿Cómo? Añadimos un archivo <code>pages/blog/[id].js</code>. Este archivo manejará todas las URLs dinámicas bajo la ruta <code>/blog/</code>, como las que mencionamos anteriormente: <code>/blog/hello-world</code>, <code>/blog/my-second-post</code> y más.</p><p>En el nombre del archivo, <code>[id]</code> dentro de los corchetes significa que cualquier cosa que sea dinámica será puesta dentro del parámetro <code>id</code> de la <strong>propiedad query </strong>del <strong>enrutador</strong>.</p><p>Vale, son demasiadas cosas a la vez.</p><p>¿Qué es el <strong>enrutador?</strong></p><p>El enrutador es una biblioteca proporcionada por Next.js.</p><p>Lo importamos desde <code>next/router</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">import { useRouter } from 'next/router'
</code></pre><figcaption>importar enrutador</figcaption></figure><p>y una vez que tenemos <code>useRouter</code>, instanciamos el objeto router usando:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">const router = useRouter()
</code></pre><figcaption>Hook para usar el enrutador</figcaption></figure><p>Una vez que tenemos este objeto router, podemos extraer información de él.</p><p>En particular, podemos obtener la parte dinámica de la URL en el archivo <code>[id].js</code> accediendo a <code>router.query.id</code>.</p><p>La parte dinámica también puede ser sólo una parte de la URL, como <code>post-[id].js</code>.</p><p>Así que vamos a seguir adelante y aplicar todas esas cosas en la práctica.</p><p>Crea el archivo <code>pages/blog/[id].js</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">import { useRouter } from 'next/router'

export default () =&gt; {
  const router = useRouter()

  return (
    &lt;&gt;
      &lt;h1&gt;Blog post&lt;/h1&gt;
      &lt;p&gt;Post id: {router.query.id}&lt;/p&gt;
    &lt;/&gt;
  )
}
</code></pre><figcaption>Uso del Hook useRouter</figcaption></figure><p>Ahora si vas al router <code>http://localhost:3000/blog/test</code>, deberías ver esto:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-05-at-16.41.32.png" class="kg-image" alt="Componente renderizado Blog con uso enrutador" width="600" height="400" loading="lazy"><figcaption>Componente renderizado Blog con uso enrutador</figcaption></figure><p>Podemos utilizar este parámetro <code>id</code> para recoger el artículo de una lista de articulos. De una base de datos, por ejemplo. Para mantener las cosas simples vamos a añadir un archivo<code>posts.json</code> en la carpeta raíz del proyecto:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">{
  "test": {
    "title": "test post",
    "content": "Hey some post content"
  },
  "second": {
    "title": "second post",
    "content": "Hey this is the second post content"
  }
}
</code></pre><figcaption>Json con los diferentes artículos o posts</figcaption></figure><p>Ahora podemos importarlo y buscar el puesto a partir de la clave <code>id</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">import { useRouter } from 'next/router'
import posts from '../../posts.json'

export default () =&gt; {
  const router = useRouter()

  const post = posts[router.query.id]

  return (
    &lt;&gt;
      &lt;h1&gt;{post.title}&lt;/h1&gt;
      &lt;p&gt;{post.content}&lt;/p&gt;
    &lt;/&gt;
  )
}
</code></pre><figcaption>Código con los artículos</figcaption></figure><p>La recarga de la página debería mostrarnos este resultado:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-05-at-16.44.07.png" class="kg-image" alt="Componente con artículo ejemplo" width="600" height="400" loading="lazy"><figcaption>Componente con artículo ejemplo</figcaption></figure><p>Pero no es así. En su lugar, obtenemos un error en la consola, y un error en el navegador también:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-05-at-18.18.17.png" class="kg-image" alt="Error con propiedad title del artículo esta en undefined" width="600" height="400" loading="lazy"><figcaption>Error con propiedad title del artículo esta en undefined</figcaption></figure><p>¿Por qué? Porque... durante el renderizado, cuando se inicializa el componente, los datos no están ahí todavía. Veremos cómo proporcionar los datos al componente con getInitialProps en la próxima lección.</p><p>Por ahora, añade una pequeña comprobación <code>if (!post) return &lt;p&gt;&lt;/p&gt;</code> antes de devolver el JSX:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">import { useRouter } from 'next/router'
import posts from '../../posts.json'

export default () =&gt; {
  const router = useRouter()

  const post = posts[router.query.id]
  if (!post) return &lt;p&gt;&lt;/p&gt;

  return (
    &lt;&gt;
      &lt;h1&gt;{post.title}&lt;/h1&gt;
      &lt;p&gt;{post.content}&lt;/p&gt;
    &lt;/&gt;
  )
}
</code></pre><figcaption>Comprobación en caso de que un post sea indefinido</figcaption></figure><p>Ahora las cosas deberían funcionar. Inicialmente el componente se muestra sin la información dinámica <code>router.query.id</code>. Después de la representación, Next.js activa una actualización con el valor de la consulta y la página muestra la información correcta.</p><p>Y si ves el código fuente, hay una etiqueta <code>&lt;p&gt;</code>vacía en el HTML</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-05-at-18.20.58.png" class="kg-image" alt="Comprobación de código fuente artículo undefined" width="600" height="400" loading="lazy"><figcaption>Comprobación de código fuente artículo undefined</figcaption></figure><p>Pronto solucionaremos este problema que no implementa SSR y esto perjudica tanto a los tiempos de carga para nuestros usuarios, SEO y el compartir en redes sociales como ya comentamos.</p><p>Podemos completar el ejemplo del blog listando esas entradas en <code>pages/blog.js</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">import posts from '../posts.json'

const Blog = () =&gt; (
  &lt;div&gt;
    &lt;h1&gt;Blog&lt;/h1&gt;

    &lt;ul&gt;
      {Object.entries(posts).map((value, index) =&gt; {
        return &lt;li key={index}&gt;{value[1].title}&lt;/li&gt;
      })}
    &lt;/ul&gt;
  &lt;/div&gt;
)

export default Blog
</code></pre><figcaption>Componente blog listando articulos</figcaption></figure><p>Y podemos enlazarlos a las páginas individuales de los posts, importando <code>Link</code> desde <code>next/link</code> usándolo dentro del bucle de posts:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">import Link from 'next/link'
import posts from '../posts.json'

const Blog = () =&gt; (
  &lt;div&gt;
    &lt;h1&gt;Blog&lt;/h1&gt;

    &lt;ul&gt;
      {Object.entries(posts).map((value, index) =&gt; {
        return (
          &lt;li key={index}&gt;
            &lt;Link href='/blog/[id]' as={'/blog/' + value[0]}&gt;
              &lt;a&gt;{value[1].title}&lt;/a&gt;
            &lt;/Link&gt;
          &lt;/li&gt;
        )
      })}
    &lt;/ul&gt;
  &lt;/div&gt;
)

export default Blog
</code></pre><figcaption>Componente blog enlazando articulos</figcaption></figure><!--kg-card-begin: html--><h2 id="previa">Búsqueda previa</h2><!--kg-card-end: html--><p>Anteriormente mencioné como el componente <code>Link</code> Next.js puede ser usado para crear enlaces entre 2 páginas cuando lo usas en Next.js, <strong>maneja de forma transparente el enrutamiento frontend</strong> por nosotros, así que cuando un usuario hace clic en un enlace, frontend se encarga de mostrar la nueva página sin desencadenar un nuevo ciclo de petición y respuesta cliente/servidor, como sucede normalmente con las páginas web.</p><p>Hay otra cosa que Next.js hace por ti cuando utilizas <code>Link</code>.</p><p>Tan pronto como un elemento envuelto dentro de <code>&lt;Link&gt;</code> aparece en la ventana gráfica (lo que significa que es visible para el usuario del sitio web), Next.js precarga la URL a la que apunta, siempre y cuando sea un enlace local (en su sitio web), haciendo que la aplicación sea súper rápida para el espectador.</p><p>Este comportamiento sólo se activa en <strong>modo de producción</strong> (hablaremos de esto en profundidad más adelante), lo que significa que tienes que detener la aplicación si la estás ejecutando con <code>npm run dev</code>, compilar tu bundle de producción con <code>npm run build</code> y ejecutarlo con <code>npm run start</code> en su lugar.</p><p>Usando el inspector de Network(red) en DevTools te darás cuenta de que cualquier enlace por encima del pliegue, en la carga de la página, comienza la precarga tan pronto como el evento <code>load</code> se ha disparado en tu página (se dispara cuando la página está completamente cargada, y sucede después del evento <code>DOMContentLoaded</code>).</p><p>Cualquier otra etiqueta <code>Link</code> que no esté en la ventana gráfica será precargada cuando el usuario haga scroll <code>npm run dev</code>.</p><p>La precarga es automática en conexiones de alta velocidad (Wifi y 3g+), a menos que el navegador envíe el <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Save-Data">encabezado HTTP</a> <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Save-Data"><code>Save-Data</code></a>.</p><p>Usted puede optar por no precargar instancias de <code>Link</code> individuales estableciendo la prop <code>prefetch</code> a <code>false</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-jsx">&lt;Link href="/a-link" prefetch={false}&gt;
  &lt;a&gt;A link&lt;/a&gt;
&lt;/Link&gt;
</code></pre><figcaption>Precarga en falso en componente Link</figcaption></figure><!--kg-card-begin: html--><h2 id="router">Uso del router para detectar el enlace activo</h2><!--kg-card-end: html--><p>Una característica muy importante cuando se trabaja con enlaces, es determinar cuál es la URL actual y en particular asignar una clase al enlace activo, para que podamos darle un estilo diferente a los demás.</p><p>Esto es especialmente útil en la cabecera de su sitio, por ejemplo.</p><p>El componente <code>Link</code> por defecto de Next.js que se ofrece en <code>next/link</code> no hace esto automáticamente por nosotros.</p><p>Podemos crear un componente Link nosotros mismos, y lo almacenamos en un archivo <code>Link.js</code> en la carpeta Components e importamos eso en lugar del predeterminado <code>next/link</code>.</p><p>En este componente, primero importaremos React de <code>react</code>, Link de <code>next/link</code> y el hook <code>useRouter</code> de <code>next/router</code>.</p><p>Dentro del componente determinamos si el nombre de la ruta actual coincide con la <code>href</code> &nbsp;prop del componente y si es así añadimos la clase <code>selected</code> a los hijos.</p><p>Finalmente devolvemos estos niños con la clase actualizada, utilizando <code>React.cloneElement()</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">import React from 'react'
import Link from 'next/link'
import { useRouter } from 'next/router'

export default ({ href, children }) =&gt; {
  const router = useRouter()

  let className = children.props.className || ''
  if (router.pathname === href) {
    className = `${className} selected`
  }

  return &lt;Link href={href}&gt;{React.cloneElement(children, { className })}&lt;/Link&gt;
}
</code></pre><figcaption>Detectar enlace activo</figcaption></figure><!--kg-card-begin: html--><h2 id="next-router">Uso de <code>next/router</code></h2><!--kg-card-end: html--><p>Ya hemos visto cómo utilizar el componente Link para manejar el enrutamiento de forma declarativa en las aplicaciones Next.js.</p><p>Es realmente práctico gestionar el enrutamiento en JSX, pero a veces necesitas activar un cambio de enrutamiento mediante programación.</p><p>En este caso, puedes acceder directamente al enrutador Next.js, proporcionado en el paquete <code>next/router</code>, y llamar a su método <code>push()</code>.</p><p>He aquí un ejemplo de acceso al enrutador:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">import { useRouter } from 'next/router'

export default () =&gt; {
  const router = useRouter()
  //...
}
</code></pre><figcaption>Uso Hook useRouter</figcaption></figure><p>Una vez que obtenemos el objeto router invocando <code>useRouter()</code>, podemos utilizar sus métodos.</p><p>Este es el router del lado del cliente, por lo que los métodos sólo deben ser utilizados en el código frontend. La forma más fácil de asegurar esto es envolver las llamadas en el hook <code>useEffect()</code> de React o dentro de <code>componentDidMount()</code>en los componentes con estado de React.</p><p>Las más utilizadas son <code>push()</code> y <code>prefetch()</code>.</p><p><code>push()</code> nos permite desencadenar programáticamente un cambio de URL, en el frontend:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">router.push('/login')
</code></pre><figcaption>router API - push</figcaption></figure><p><code>prefetch()</code> nos permite precargar una URL programada, lo que resulta útil cuando no disponemos de una etiqueta <code>Link</code> que gestione automáticamente la precarga por nosotros:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">router.prefetch('/login')
</code></pre><figcaption>router API - prefetch</figcaption></figure><p>Ejemplo completo:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">import { useRouter } from 'next/router'

export default () =&gt; {
  const router = useRouter()

  useEffect(() =&gt; {
    router.prefetch('/login')
  })
}
</code></pre><figcaption>router API - prefetch en componente</figcaption></figure><p>También puedes utilizar el router para escuchar <a href="https://nextjs.org/docs#router-events">eventos de cambio de ruta</a>.</p><!--kg-card-begin: html--><h2 id="getinitialprops">Proporcionar datos a los componentes mediante getInitialProps</h2><!--kg-card-end: html--><p>En el capítulo anterior tuvimos un problema con la generación dinámica de la página de publicación, porque el componente requería algunos datos por adelantado y cuando intentamos obtener los datos del archivo JSON:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">import { useRouter } from 'next/router'
import posts from '../../posts.json'

export default () =&gt; {
  const router = useRouter()

  const post = posts[router.query.id]

  return (
    &lt;&gt;
      &lt;h1&gt;{post.title}&lt;/h1&gt;
      &lt;p&gt;{post.content}&lt;/p&gt;
    &lt;/&gt;
  )
}
</code></pre><figcaption>Componente Article - Post</figcaption></figure><p>Obtenemos este error:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-05-at-18.18.17-1.png" class="kg-image" alt="Screen-Shot-2019-11-05-at-18.18.17-1" width="600" height="400" loading="lazy"><figcaption>Error datos undefined</figcaption></figure><p>¿Cómo lo solucionamos? ¿Y cómo hacemos que SSR funcione para rutas dinámicas?</p><p>Debemos dotar al componente de props, utilizando una función especial llamada <code>getInitialProps()</code> que se adjunta al componente.</p><p>Para ello, primero nombramos el componente:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">const Post = () =&gt; {
  //...
}

export default Post
</code></pre><figcaption>Componente Post</figcaption></figure><p>Entonces le añadimos la función:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">const Post = () =&gt; {
  //...
}

Post.getInitialProps = () =&gt; {
  //...
}

export default Post
</code></pre><figcaption>Adición de función&nbsp;</figcaption></figure><p>Esta función obtiene como argumento un objeto que contiene varias propiedades. En concreto, lo que nos interesa ahora es que obtenga el objeto <code>query</code>, el que usamos anteriormente para obtener el id del post.</p><p><em>Así que podemos obtenerlo usando la sintaxis de desestructuración de objetos:</em></p><figure class="kg-card kg-code-card"><pre><code class="language-js">Post.getInitialProps = ({ query }) =&gt; {
  //...
}
</code></pre><figcaption>Desestructuración de Props</figcaption></figure><p>Ahora podemos devolver el post desde esta función:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">Post.getInitialProps = ({ query }) =&gt; {
  return {
    post: posts[query.id]
  }
}
</code></pre><figcaption>getInitialProps -&nbsp;</figcaption></figure><p>Y también podemos eliminar la importación de <code>useRouter</code> y obtenemos el post de la propiedad <code>props</code> pasada al componente <code>Post</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">import posts from '../../posts.json'

const Post = props =&gt; {
  return (
    &lt;div&gt;
      &lt;h1&gt;{props.post.title}&lt;/h1&gt;
      &lt;p&gt;{props.post.content}&lt;/p&gt;
    &lt;/div&gt;
  )
}

Post.getInitialProps = ({ query }) =&gt; {
  return {
    post: posts[query.id]
  }
}

export default Post
</code></pre><figcaption>Obtención de props basados en getInitialProps</figcaption></figure><p>Ahora no habrá ningún error, el SSR estará funcionando como se esperaba, como se puede ver comprobando la vista fuente:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-05-at-18.53.02.png" class="kg-image" alt="Código fuente con getInitialProps" width="600" height="400" loading="lazy"><figcaption>Código fuente con getInitialProps</figcaption></figure><p>La función <code>getInitialProps</code> se ejecutará en el lado del servidor, pero también en el lado del cliente, cuando naveguemos a una nueva página utilizando el componente <code>Link</code> como hemos hecho.</p><p>Es importante tener en cuenta que <code>getInitialProps</code> obtiene el objeto de contexto que recibe, además del objeto de <code>query</code>(consulta) estas otras propiedades:</p><ul><li><code>pathname</code>: la sección <code>path</code> de la URL</li><li><code>asPath</code>: Cadena de texto de la ruta real (incluida la consulta) que se muestra en el navegador</li></ul><p>que en el caso de llamar a<code>http://localhost:3000/blog/test</code> dará como resultado respectivamente:</p><ul><li><code>/blog/[id]</code></li><li><code>/blog/test</code></li></ul><p>Y en el caso del renderizado del lado del servidor, también recibirá:</p><ul><li><code>req</code>: el objeto de solicitud HTTP</li><li><code>res</code>: el objeto de respuesta HTTP</li><li><code>err</code>: un objeto de error</li></ul><p><code>req</code> y <code>res</code> te resultarán familiares si has codificado con Node.js.</p><h2 id="css">CSS</h2><p>¿Cómo damos estilo a los componentes React en Next.js?</p><p>Tenemos mucha libertad, porque podemos usar la librería de nuestra preferencia.</p><p>Pero Next.js viene con <a href="https://github.com/zeit/styled-jsx"><code>styled-jsx</code></a> incorporado, porque es una librería construida por la misma gente que trabaja en Next.js.</p><p>Se trata de una biblioteca muy interesante que nos proporciona CSS de ámbito limitado, lo que resulta muy útil para el mantenimiento, ya que el CSS sólo afecta al componente al que se aplica.</p><p>Creo que este es un gran enfoque para escribir CSS, sin la necesidad de aplicar bibliotecas adicionales o preprocesadores que añaden complejidad.</p><p>Para añadir CSS a un componente React en Next.js lo insertamos dentro de un snippet en el JSX, que empieza por</p><figure class="kg-card kg-code-card"><pre><code class="language-js">&lt;style jsx&gt;{`
</code></pre><figcaption>Snippet JSX de estilo de apertura</figcaption></figure><p>y termina con</p><figure class="kg-card kg-code-card"><pre><code class="language-js">`}&lt;/style&gt;
</code></pre><figcaption>Snippet JSX de estilo de cierre</figcaption></figure><p>Dentro de estos extraños bloques escribimos CSS plano, como haríamos en un archivo <code>.css</code>:</p><pre><code class="language-js">&lt;style jsx&gt;{`
  h1 {
    font-size: 3rem;
  }
`}&lt;/style&gt;
</code></pre><p>Lo escribes dentro del JSX, así:</p><pre><code class="language-js">const Index = () =&gt; (
  &lt;div&gt;
		&lt;h1&gt;Home page&lt;/h1&gt;

		&lt;style jsx&gt;{`
		  h1 {
		    font-size: 3rem;
		  }
		`}&lt;/style&gt;
  &lt;/div&gt;
)

export default Index
</code></pre><p>Dentro del bloque podemos utilizar la interpolación para cambiar dinámicamente los valores. Por ejemplo, aquí suponemos que el componente padre pasa una propiedad de <code>size</code> y la utilizamos en el bloque <code>styled-jsx</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">const Index = props =&gt; (
  &lt;div&gt;
		&lt;h1&gt;Home page&lt;/h1&gt;

		&lt;style jsx&gt;{`
		  h1 {
		    font-size: ${props.size}rem;
		  }
		`}&lt;/style&gt;
  &lt;/div&gt;
)
</code></pre><figcaption>Componente Index con estilos en el título</figcaption></figure><p>Si desea aplicar un CSS de forma global, no limitado a un componente, añada la palabra clave <code>global</code> a la etiqueta <code>style</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-jsx">&lt;style jsx global&gt;{`
body {
  margin: 0;
}
`}&lt;/style&gt;
</code></pre><figcaption>Estilos globales</figcaption></figure><p>Si quieres importar un archivo CSS externo en un componente Next.js, primero tienes que instalar <code>@zeit/next-css</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-bash">npm install @zeit/next-css
</code></pre><figcaption>Paquete para componente externo</figcaption></figure><p>Luego creas un archivo de configuración en la raíz del proyecto, llamado <code>next.config.js</code>, con este contenido:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">const withCSS = require('@zeit/next-css')
module.exports = withCSS()
</code></pre><figcaption>Configuración Paquete zeit</figcaption></figure><p>Tras reiniciar la aplicación Next, ya puedes importar CSS como haces normalmente con las bibliotecas o componentes JavaScript:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">import '../style.css'
</code></pre><figcaption>Importar CSS debido a zeit</figcaption></figure><p>También puede importar un archivo SASS directamente, utilizando en su lugar la biblioteca <a href="https://github.com/zeit/next-plugins/tree/master/packages/next-sass"><code>@zeit/next-sass</code></a>.</p><!--kg-card-begin: html--><h2 id="tags">Rellenar la etiqueta head con etiquetas personalizadas</h2><!--kg-card-end: html--><p>Desde cualquier componente de página Next.js, puede añadir información a la cabecera de la página.</p><p>Esto es útil cuando:</p><ul><li>Desea personalizar el título de la página</li><li>Desea cambiar una etiqueta <code>meta</code></li></ul><p>¿Cómo puedes hacerlo?</p><p>Dentro de cada componente puedes importar el componente <code>Head</code> desde <code>next/head</code> e incluirlo en la salida JSX de tu componente:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">import Head from 'next/head'

const House = props =&gt; (
  &lt;div&gt;
    &lt;Head&gt;
      &lt;title&gt;The page title&lt;/title&gt;
    &lt;/Head&gt;
    {/* Resto de JSX */}
  &lt;/div&gt;
)

export default House
</code></pre><figcaption>Modificar etiqueta Head</figcaption></figure><p>Puedes añadir cualquier etiqueta HTML que quieras que aparezca en la sección <code>&lt;head&gt;</code> de la página.</p><p>Al montar el componente, Next.js se asegurará de que las etiquetas dentro de <code>Head</code> se añadan al encabezado de la página. Lo mismo al desmontar el componente, Next.js se encargará de eliminar esas etiquetas.</p><!--kg-card-begin: html--><h2 id="wrapper">Añadir un componente envoltorio(wrapper component)</h2><!--kg-card-end: html--><p>Todas las páginas de tu sitio tienen más o menos el mismo aspecto. Hay una ventana chrome, una capa base común y sólo quieres cambiar lo que hay dentro.</p><p>Hay una barra de navegación, una barra lateral, y luego el contenido real.</p><p>¿Cómo se construye este sistema en Next.js?</p><p>Hay dos maneras. Una es usando un <a href="https://flaviocopes.com/react-higher-order-components/">Componente de Orden Superior</a><strong>(HOC)</strong>, creando un componente <code>components/Layout.js</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">export default Page =&gt; {
  return () =&gt; (
    &lt;div&gt;
      &lt;nav&gt;
        &lt;ul&gt;....&lt;/ul&gt;
      &lt;/hav&gt;
      &lt;main&gt;
        &lt;Page /&gt;
      &lt;/main&gt;
    &lt;/div&gt;
  )
}
</code></pre><figcaption>componente Page</figcaption></figure><p>Ahí podemos importar componentes separados para el encabezado y/o la barra lateral y también podemos añadir todo el CSS que necesitemos.</p><p>Y lo usas en cada página así:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">import withLayout from '../components/Layout.js'

const Page = () =&gt; &lt;p&gt;Here's a page!&lt;/p&gt;

export default withLayout(Page)
</code></pre><figcaption>Componente de Orden Superior</figcaption></figure><p>Pero encontré que esto funciona sólo para casos simples, donde no es necesario llamar a <code>getInitialProps()</code> en una página.</p><p>¿Por qué?</p><p>Porque <code>getInitialProps()</code> sólo se llama en el componente página. Pero si exportamos el componente de orden superior<strong>(HOC)</strong> <code>withLayout()</code> desde una página, <code>Page.getInitialProps()</code> no es llamado. <code>withLayout.getInitialProps()</code> sí lo sería.</p><p>Para evitar complicar innecesariamente nuestra base de código, el enfoque alternativo es utilizar props:</p><pre><code class="language-js">export default props =&gt; (
  &lt;div&gt;
    &lt;nav&gt;
      &lt;ul&gt;....&lt;/ul&gt;
    &lt;/hav&gt;
    &lt;main&gt;
      {props.content}
    &lt;/main&gt;
  &lt;/div&gt;
)
</code></pre><p>y en nuestras páginas ahora lo usamos así:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">import Layout from '../components/Layout.js'

const Page = () =&gt; (
  &lt;Layout content={(
    &lt;p&gt;Here's a page!&lt;/p&gt;
  )} /&gt;
)
</code></pre><figcaption>Pasar componente mediante Props</figcaption></figure><p>Este enfoque nos permite utilizar <code>getInitialProps()</code> dentro de nuestro componente de página, con el único inconveniente de tener que escribir el componente JSX dentro del prop <code>content</code>:</p><pre><code class="language-js">import Layout from '../components/Layout.js'

const Page = () =&gt; (
  &lt;Layout content={(
    &lt;p&gt;Here's a page!&lt;/p&gt;
  )} /&gt;
)

Page.getInitialProps = ({ query }) =&gt; {
  //...
}
</code></pre><!--kg-card-begin: html--><h2 id="api-routes">API Routes</h2><!--kg-card-end: html--><p>Además de crear <strong>rutas de página(page routes)</strong>, lo que significa que las páginas se sirven al navegador como páginas web, Next.js puede crear <strong>rutas API(API routes)</strong>.</p><p>Esta es una característica muy interesante porque significa que Next.js puede utilizarse para crear un frontend para datos que son almacenados y recuperados por el propio Next.js, transfiriendo JSON a través de peticiones fetch.</p><p>Las rutas API viven bajo la carpeta <code>/pages/api/</code> y están mapeadas al endpoint <code>/api</code>.</p><p>Esta característica es muy útil a la hora de crear aplicaciones.</p><p>En esas rutas, escribimos código Node.js (en lugar de código React). Es un cambio de paradigma, pasas del frontend al backend, pero muy fluido.</p><p>Imagina que tienes un archivo <code>/pages/api/comments.js</code>, cuyo objetivo es devolver los comentarios de una entrada de blog como JSON.</p><p>Digamos que tienes una lista de comentarios almacenados en un archivo <code>comments.json</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-json">[
  {
    "comment": "First"
  },
  {
    "comment": "Nice post"
  }
]
</code></pre><figcaption>JSON de artículos</figcaption></figure><p>He aquí un ejemplo de código, que devuelve al cliente la lista de comentarios:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">import comments from './comments.json'

export default (req, res) =&gt; {
  res.status(200).json(comments)
}
</code></pre><figcaption>Retornar comentarios en JSON</figcaption></figure><p>Esto escuchará en la URL <code>/api/comments</code> para peticiones GET, puedes intentar llamarlo usando tu navegador:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-07-at-11.14.42.png" class="kg-image" alt="JSON retornado del servidor" width="600" height="400" loading="lazy"><figcaption>JSON retornado del servidor</figcaption></figure><p>Las rutas del API pueden utilizar <strong>enrutamiento dinámico</strong> como las páginas, use la sintaxis <code>[]</code> para crear una ruta de API dinámica, como <code>/pages/api/comments/[id].js</code> que recuperará los comentarios específicos de un <code>id</code> de entrada.</p><p>Dentro de <code>[id].js</code> puedes recuperar el valor del <code>id</code> buscándolo dentro del objeto <code>req.query</code>:</p><pre><code class="language-js">import comments from '../comments.json'

export default (req, res) =&gt; {
  res.status(200).json({ post: req.query.id, comments })
}
</code></pre><p>Aquí puedes ver el código anterior en acción:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-07-at-11.59.53.png" class="kg-image" alt="SId de los artículos" width="600" height="400" loading="lazy"><figcaption>Id de los artículos</figcaption></figure><p>En páginas dinámicas, tendrías que importar <code>useRouter</code> de <code>next/router</code>, luego obtener el objeto router usando <code>const router = useRouter()</code>, luego podríamos obtener el valor <code>id</code> usando <code>router.query.id</code>.</p><p>En el lado del servidor todo es más fácil, ya que la consulta se adjunta al objeto de solicitud.</p><p>Si haces una petición POST, todo funciona de la misma manera - todo va a través de esa exportación por defecto.</p><p>Para separar POST de GET y otros métodos HTTP (PUT, DELETE), busca el valor <code>req.method</code>:</p><pre><code class="language-js">export default (req, res) =&gt; {
  switch (req.method) {
    case 'GET':
      //...
      break
    case 'POST':
      //...
      break
    default:
      res.status(405).end() //Method Not Allowed
      break
  }
}
</code></pre><p>Además de <code>req.query</code> y <code>req.method</code> que ya vimos, tenemos acceso a las cookies haciendo referencia a <code>req.cookies</code>, el cuerpo de la petición en <code>req.body</code>.</p><p>Bajo el capó, todo esto es impulsado por <a href="https://github.com/zeit/micro">Micro</a>, una biblioteca que impulsa microservicios HTTP asíncronos, hecha por el mismo equipo que construyó Next.js.</p><p>Puedes hacer uso de cualquier middleware Micro en nuestras rutas API para añadir más funcionalidad.</p><!--kg-card-begin: html--><h2 id="server">Ejecutar código sólo en el lado del servidor o en el lado del cliente</h2><!--kg-card-end: html--><p>En tus componentes de página, puedes ejecutar código sólo en el lado del servidor o en el lado del cliente, comprobando la propiedad <code>window</code>.</p><p>Esta propiedad sólo existe dentro del navegador, puedes comprobar</p><pre><code class="language-js">if (typeof window === 'undefined') {

}
</code></pre><p>y añadir el código del lado del servidor en ese bloque.</p><p>Del mismo modo, puede ejecutar código del lado del cliente sólo comprobando</p><pre><code class="language-js">if (typeof window !== 'undefined') {

}
</code></pre><p>Consejo JS: Usamos el operador <code>typeof</code> aquí porque no podemos detectar que un valor sea undefined de otra forma. No podemos hacer <code>if (window === undefined)</code> porque obtendríamos un error de ejecución "window is not defined".</p><p>Next.js, como optimización en tiempo de compilación, también elimina de los paquetes el código que utiliza esas comprobaciones. Un paquete del lado del cliente no incluirá el contenido envuelto en un bloque <code>if (typeof window === 'undefined') {}</code>.</p><!--kg-card-begin: html--><h2 id="despliegue">Despliegue de la versión de producción</h2><!--kg-card-end: html--><p>El despliegue de una aplicación siempre se deja para el final en los tutoriales.</p><p>Aquí quiero introducirlo antes, sólo porque es tan fácil desplegar una aplicación Next.js que podemos sumergirnos en ello ahora, y luego pasar a otros temas más complejos más adelante.</p><p>Recuerda que en el capítulo "Cómo instalar Next.js" te dije que añadieras esas 3 líneas a la sección del <code>script package.json</code>:</p><pre><code class="language-json">"scripts": {
  "dev": "next",
  "build": "next build",
  "start": "next start"
}
</code></pre><p>Hasta ahora usábamos <code>npm run dev</code>, para llamar al comando <code>next</code> instalado localmente en <code>node_modules/next/dist/bin/next</code>. Esto inició el servidor de desarrollo, que nos proporcionó <strong>mapas de código fuente(sourcemaps)</strong> y <strong>recarga de código en caliente(hot code reloading)</strong>, dos características muy útiles durante la depuración.</p><p>El mismo comando puede ser invocado para construir el sitio web pasando la bandera build, ejecutando <code>npm run build</code>. A continuación, el mismo comando se puede utilizar para iniciar la aplicación de producción pasando la bandera <code>start</code>, ejecutando <code>npm run start</code>.</p><p>Esos 2 comandos son los que debemos invocar para desplegar con éxito la versión de producción de nuestro sitio localmente. La versión de producción está altamente optimizada y no viene con <strong>mapas de fuentes(sourcemaps)</strong> y otras cosas como la <strong>recarga de código en caliente(hot code reloading)</strong> que no sería beneficioso para nuestros usuarios finales.</p><p>Por lo tanto, vamos a crear un despliegue de producción de nuestra aplicación. Construirlo usando:</p><pre><code class="language-bash">npm run build
</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-06-at-13.46.31.png" class="kg-image" alt="Construir paquete de aplicaciones(app bundle)" width="600" height="400" loading="lazy"><figcaption>Construir paquete de aplicaciones(app bundle)</figcaption></figure><p>La salida del comando nos dice que algunas rutas (<code>/</code> y <code>/blog</code> están ahora prerenderizadas como HTML estático, mientras que <code>/blog/[id]</code> será servido por el backend Node.js.</p><p>A continuación, puede ejecutar <code>npm run start</code> para iniciar el servidor de producción localmente:</p><pre><code class="language-bash">npm run start
</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-06-at-13.47.01.png" class="kg-image" alt="npm run start" width="600" height="400" loading="lazy"><figcaption>npm run start</figcaption></figure><p>Visitar <a href="http://localhost:3000">http://localhost:3000</a> nos muestra la versión de producción de la aplicación, localmente.</p><!--kg-card-begin: html--><h2 id="now">Despliegue en Now</h2>
<!--kg-card-end: html--><p>En el capítulo anterior desplegamos la aplicación Next.js localmente.</p><p>Cómo la desplegamos en un servidor web real, para que otras personas puedan acceder a ella?</p><p>Una de las formas más sencillas de desplegar una aplicación Next es a través de la plataforma <strong>Now</strong> creada por <a href="https://zeit.co">Zeit</a>, la misma empresa que creó el proyecto Open Source Next.js. Puedes utilizar Now para desplegar aplicaciones Node.js, sitios web estáticos y mucho más.</p><p>Ahora hace que el paso de despliegue y distribución de una aplicación sea muy, muy sencillo y rápido, y además de aplicaciones Node.js, también admite el despliegue de Go, PHP, Python y otros lenguajes.</p><p>Puedes pensar en ella como en la "nube", ya que no sabes realmente dónde se desplegará tu aplicación, pero sabes que tendrás una URL a la que podrás acceder.</p><p>Now es gratuito para empezar a usarlo, con un generoso plan gratuito que actualmente incluye 100 GB de alojamiento, 1000 invocaciones de funciones <a href="https://www.freecodecamp.org/news/serverless/">serverless</a>, 1000 invocaciones al mes, 100 GB de ancho de banda al mes y una ubicación <a href="https://www.freecodecamp.org/news/cdn/">CDN</a>. La <a href="https://zeit.co/pricing">página de precios</a> ayuda a hacerse una idea de los costes si necesita más.</p><p>La mejor manera de empezar a usar Now es utilizando la CLI oficial de Now:</p><pre><code class="language-bash">npm install -g now
</code></pre><p>Una vez que el comando esté disponible, ejecute</p><pre><code class="language-bash">now login
</code></pre><p>La aplicación te pide el correo electrónico.</p><p>Si aún no se ha registrado, cree una cuenta en <a href="https://zeit.co/signup">https://zeit.co/signup</a> antes de continuar y, a continuación, añada su dirección de correo electrónico al cliente CLI.</p><p>Una vez hecho esto, desde la carpeta raíz del proyecto Next.js ejecuta</p><pre><code class="language-bash">now
</code></pre><p>y la aplicación se desplegará instantáneamente en la nube de Now y se le proporcionará la URL única de la aplicación:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-06-at-14.21.09.png" class="kg-image" alt="Screen-Shot-2019-11-06-at-14.21.09" width="600" height="400" loading="lazy"></figure><p>Una vez ejecutado el programa <code>now</code>, la aplicación se despliega en una URL aleatoria bajo el dominio <code>now.sh</code>.</p><p>Podemos ver 3 URLs diferentes en la salida dada en la imagen:</p><ul><li><a href="https://firstproject-2pv7khwwr.now.sh">https://firstproject-2pv7khwwr.now.sh</a></li><li><a href="https://firstproject-sepia-ten.now.sh">https://firstproject-sepia-ten.now.sh</a></li><li><a href="https://firstproject.flaviocopes.now.sh">https://firstproject.flaviocopes.now.sh</a></li></ul><p>¿Por qué tantos?<br>La primera es la URL que identifica el despliegue. Cada vez que despleguemos la aplicación, esta URL cambiará.</p><p>Usted puede probar inmediatamente cambiando algo en el código del proyecto y ejecutar de nuevo el comando <code>now</code>:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-06-at-15.08.11.png" class="kg-image" alt="Proyecto desplegado en now" width="600" height="400" loading="lazy"><figcaption>Proyecto desplegado en now</figcaption></figure><p>Las otras 2 URLs no cambiarán. La primera es aleatoria, la segunda es el nombre de tu proyecto (que por defecto es la carpeta del proyecto actual, tu nombre de cuenta y luego <code>now.sh</code>.</p><p>Si visitas la URL, verás la aplicación desplegada en producción.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-06-at-14.21.43.png" class="kg-image" alt="Aplicación en producción" width="600" height="400" loading="lazy"><figcaption>Aplicación en producción</figcaption></figure><p>Usted puede configurar Now para servir el sitio a su propio dominio personalizado o subdominio, pero no voy a adentrarme en eso ahora.</p><p>El subdominio <code>now.sh</code> es suficiente para nuestras pruebas.</p><!--kg-card-begin: html--><h2 id="paquetes">Análisis de los paquetes de aplicaciones</h2>
<!--kg-card-end: html--><p>Next nos proporciona una forma de analizar los paquetes de código que se generan.</p><p>Abre el archivo package.json de la app y en la sección scripts añade estos 3 nuevos comandos:</p><figure class="kg-card kg-code-card"><pre><code class="language-json">"analyze": "cross-env ANALYZE=true next build",
"analyze:server": "cross-env BUNDLE_ANALYZE=server next build",
"analyze:browser": "cross-env BUNDLE_ANALYZE=browser next build"
</code></pre><figcaption>Comandos para analizar paquetes</figcaption></figure><p>Asi:</p><figure class="kg-card kg-code-card"><pre><code class="language-json">{
  "name": "firstproject",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start",
    "analyze": "cross-env ANALYZE=true next build",
    "analyze:server": "cross-env BUNDLE_ANALYZE=server next build",
    "analyze:browser": "cross-env BUNDLE_ANALYZE=browser next build"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "next": "^9.1.2",
    "react": "^16.11.0",
    "react-dom": "^16.11.0"
  }
}
</code></pre><figcaption>package.json</figcaption></figure><p>y luego instale esos 2 paquetes:</p><pre><code class="language-bash">npm install --dev cross-env @next/bundle-analyzer
</code></pre><p>Crea un archivo <code>next.config.js</code> en la raíz del proyecto, con este contenido:</p><pre><code class="language-js">const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true'
})

module.exports = withBundleAnalyzer({})
</code></pre><p>Ahora ejecute el comando</p><pre><code class="language-bash">npm run analyze
</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-06-at-16.12.40.png" class="kg-image" alt="Screen-Shot-2019-11-06-at-16.12.40" width="600" height="400" loading="lazy"></figure><p>Esto debería abrir 2 páginas en el navegador. Una para los paquetes cliente y otra para los paquetes servidor:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-06-at-16.11.14.png" class="kg-image" alt="Análisis de paquetes del cliente" width="600" height="400" loading="lazy"><figcaption>Análisis de paquetes del cliente</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-06-at-16.11.23.png" class="kg-image" alt="Análisis de paquetes del servidor" width="600" height="400" loading="lazy"><figcaption>Análisis de paquetes del servidor</figcaption></figure><p>Esto es increíblemente útil. Puedes inspeccionar lo que está ocupando más espacio en los paquetes, y también puedes utilizar la barra lateral para excluir paquetes, para una visualización más fácil de los más pequeños:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-06-at-16.14.12.png" class="kg-image" alt="Filtro de resultados de análisis paquetes" width="600" height="400" loading="lazy"><figcaption>Filtro de resultados de análisis paquetes</figcaption></figure><!--kg-card-begin: html--><h2 id="carga">Módulos de carga diferida</h2>
<!--kg-card-end: html--><p>Poder analizar visualmente un bundle es genial, porque podemos optimizar nuestra aplicación de una manera adecuada.</p><p>Digamos que necesitamos cargar la librería Moment en nuestro blog posts. Ejecuta:</p><pre><code class="language-bash">npm install moment
</code></pre><p>para incluirlo en el proyecto.</p><p>Ahora vamos a simular que lo necesitamos en dos rutas diferentes: <code>/blog</code> y <code>/blog/[id]</code>.</p><p>Lo importamos en <code>pages/blog/[id].js</code>:</p><pre><code class="language-jsx">import moment from 'moment'

...

const Post = props =&gt; {
  return (
    &lt;div&gt;
      &lt;h1&gt;{props.post.title}&lt;/h1&gt;
      &lt;p&gt;Published on {moment().format('dddd D MMMM YYYY')}&lt;/p&gt;
      &lt;p&gt;{props.post.content}&lt;/p&gt;
    &lt;/div&gt;
  )
}
</code></pre><p>Sólo estoy añadiendo la fecha de hoy, como ejemplo.</p><p>Esto incluirá Moment.js en el paquete de la página de la entrada del blog, como puedes ver ejecutando <code>npm run analyze</code>:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-06-at-17.56.14.png" class="kg-image" alt="Screen-Shot-2019-11-06-at-17.56.14" width="600" height="400" loading="lazy"></figure><p>Observa que ahora tenemos una entrada roja en <code>/blog/[id]</code>, ¡la ruta a la que añadimos Moment.js!</p><p>Ha pasado de ~1kB a 350kB, una gran cosa. Y esto se debe a que la propia biblioteca Moment.js ocupa 349kB.</p><p>La visualización de bundles del cliente nos muestra ahora que el bundle más grande es el de la página, que antes era muy poco. Y el 99% de su código es Moment.js.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-06-at-17.55.50.png" class="kg-image" alt="Screen-Shot-2019-11-06-at-17.55.50" width="600" height="400" loading="lazy"></figure><p>Cada vez que cargamos una entrada de blog vamos a tener todo este código transferido al cliente. Lo cual no es lo ideal.</p><p>Una solución sería buscar una biblioteca con un tamaño más pequeño, como Moment.js no es conocido por ser ligero (especialmente fuera de la caja con todos los locales incluidos), pero vamos a suponer por el bien del ejemplo que debemos usarlo.</p><p>Lo que podemos hacer en su lugar es separar todo el código de Moment en un <strong>paquete separado.</strong></p><p>¿Cómo? En lugar de importar Moment a nivel de componente, realizamos una importación asíncrona dentro de <code>getInitialProps</code> y calculamos el valor a enviar al componente.</p><p>Recuerda que no podemos devolver objetos complejos dentro del objeto devuelto por <code>getInitialProps()</code>, así que calculamos la fecha dentro de él:</p><pre><code class="language-js">import posts from '../../posts.json'

const Post = props =&gt; {
  return (
    &lt;div&gt;
      &lt;h1&gt;{props.post.title}&lt;/h1&gt;
      &lt;p&gt;Published on {props.date}&lt;/p&gt;
      &lt;p&gt;{props.post.content}&lt;/p&gt;
    &lt;/div&gt;
  )
}

Post.getInitialProps = async ({ query }) =&gt; {
  const moment = (await import('moment')).default()
  return {
    date: moment.format('dddd D MMMM YYYY'),
    post: posts[query.id]
  }
}

export default Post
</code></pre><p>¿Ves esa llamada especial a <code>.default()</code> después de <code>await import</code>? Es necesaria para hacer referencia a la exportación por defecto en una importación dinámica (véase <a href="https://v8.dev/features/dynamic-import">https://v8.dev/features/dynamic-import</a>)</p><p>Ahora si ejecutamos <code>npm run analyze</code> de nuevo, podemos ver esto:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-06-at-18.00.22.png" class="kg-image" alt="Screen-Shot-2019-11-06-at-18.00.22" width="600" height="400" loading="lazy"></figure><p>Nuestro bundle <code>/blog/[id]</code> vuelve a ser muy pequeño, ya que Moment se ha trasladado a su propio archivo bundle, cargado por separado por el navegador.</p><!--kg-card-begin: html--><h2 id="ahora">¿Qué hacer a partir de ahora?</h2>
<!--kg-card-end: html--><p>Hay mucho más que saber sobre Next.js. No he hablado de la gestión de sesiones de usuario con login, serverless, gestión de bases de datos, etc.</p><p>El objetivo de este Manual no es enseñártelo todo, sino introducirte, poco a poco, el potencial de Next.js.</p><p>El siguiente paso que recomiendo es leer detenidamente la <a href="https://nextjs.org/docs">documentación oficial de Next.js</a> para obtener más información sobre todas las características y funcionalidades de las que no he hablado y echar un vistazo a todas las funcionalidades adicionales introducidas por los <a href="https://github.com/zeit/next-plugins">plugins de Next.js</a>, algunas de las cuales son bastante sorprendentes.</p><p>Puedes ponerte en contacto conmigo en Twitter <a href="https://twitter.com/flaviocopes">@flaviocopes.</a></p><p>Visite también mi sitio web, <a href="https://flaviocopes.com/">flaviocopes.com</a>.</p><p><a href="https://flaviocopes.com/page/nextjs-handbook/">Nota: puede descargar una versión PDF / ePub / Mobi de este tutorial para poder leerlo sin conexión.</a></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Breve introducción a la desestructuración de arreglos en ES6 ]]>
                </title>
                <description>
                    <![CDATA[ La desestructuración en JavaScript es un método simplificado para extraer múltiples propiedades de un arreglo tomando la estructura y deconstruyéndola en sus partes integrantes mediante asignaciones, esto usa una sintaxis similar a la de los literales de arreglo. Crea un patrón que describe el tipo de valor que espera y ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/breve-introduccion-a-la-desestructuracion-de-arreglos-en-es6/</link>
                <guid isPermaLink="false">646bfc08a7154006ea79e2fb</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Santiago Toquica Yanguas ]]>
                </dc:creator>
                <pubDate>Sun, 11 Jun 2023 00:20:13 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2023/06/1_5TN-55RU-eTfNlcDL2RR1g.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/array-destructuring-in-es6-30e398f21d10/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">A Brief Introduction to Array Destructuring in ES6</a>
      </p><p>La <strong>desestructuración</strong> en JavaScript es un método simplificado para extraer múltiples propiedades de un arreglo tomando la estructura y deconstruyéndola en sus partes integrantes mediante asignaciones, esto usa una sintaxis similar a la de los literales de arreglo.</p><p>Crea un patrón que describe el tipo de valor que espera y realiza la asignación. La desestructuración de arreglos usa la posición de manera ordenada.</p><p>Véase el siguiente fragmento de código.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let [primero, segundo, tercero] = ["Laide", "Gabriel", "Jets"];</code></pre><figcaption>Sintaxis con desestructuración</figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-js">let primero = "laide",
    segundo = "Gabriel",
    tercero = "Jets";</code></pre><figcaption>Sintaxis sin desestructuración</figcaption></figure><blockquote>No se pueden usar números para desestructurar. Numeros producirá un error porque los números no pueden ser nombres de variables en JS.</blockquote><figure class="kg-card kg-code-card"><pre><code class="language-js">let [1, 2, 3] = ["Laide", "Ola", "Jets"];</code></pre><figcaption>Desestructuración errónea</figcaption></figure><p><em>Esta sintaxis provoca un error.</em></p><p></p><p>La <strong>desestructuración</strong> ha hecho que extraer datos de un arreglo sea muy sencillo y legible. Imagina intentar extraer datos de un arreglo anidado con 5 o 6 niveles. Sería muy tedioso. Se utiliza un literal de arreglo en el lado izquierdo de la asignación.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let cosa = ["Mesa", "Silla", "Ventilador"];
let [a, b, c] = cosa;</code></pre><figcaption>Desestructuración de variable cosa</figcaption></figure><p>Toma cada variable del literal del arreglo en el lado izquierdo y la mapea al mismo elemento en el mismo índice del arreglo.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">console.log(a); // Salida: Mesa
console.log(b); // Salida: Silla
console.log(c); // Salida: Ventilador</code></pre><figcaption>Salida</figcaption></figure><p>La declaración y la asignación pueden realizarse por separado en la desestructuración.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let primero, segundo;
[primero, segundo] = ["Hombre", "Mujer"];</code></pre><figcaption>Asignación de valores mediante desestructuración</figcaption></figure><p>Si el número de variables pasadas a los literales del arreglo de desestructuración es mayor que los elementos del arreglo, entonces las variables que no están mapeadas a ningún elemento del arreglo devuelven <code>undefined</code>.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let cosas = ["Mesa", "Silla", "Ventilador", "Alfombra"];
let [a, b, c, d, e] = cosas;
console.log(c); // Salida: Ventilador
console.log(d); // Salida: Alfombra
console.log(e); // Salida: undefined</code></pre><figcaption>Desestructuración de variable cosa</figcaption></figure><p>Si el número de variables pasadas a los literales del arreglo de desestructuración es menor que los elementos del arreglo, se dejan los elementos sin variables a los que mapear. No se produce ningún error.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let cosas = ["Mesa", "Silla", "Ventilador", "Alfombra"];
cosas [a, b, c] = cosas;
console.log(c); // Salida: Ventilador</code></pre><figcaption>Desestructuración de variable cosas</figcaption></figure><h3 id="desestructuraci-n-de-arreglos-retornados"><strong>Desestructuración de arreglos retornados</strong></h3><p>La desestructuración hace que trabajar con una función que devuelve un arreglo como valor sea más preciso. Funciona para todos los iterables.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">function corredoras(){
    return ["Sandra", "Ola", "Chi"];
}

let [a, b, c] = corredoras();
console.log(a); // Salida: Sandra
console.log(b); // Salida: Ola
console.log(c); // Salida: Chi</code></pre><figcaption>Desestructuración de resultado de una función</figcaption></figure><h3 id="valor-por-defecto"><strong>Valor por defecto</strong></h3><p>La desestructuración permite asignar un valor por defecto a una variable si no se pasa ningún valor o <code>undefined</code>. Es proporcionar una alternativa cuando no se encuentra nada.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let a, b;
[a = 40, b = 4] = [];
console.log(a); // Salida: 40
console.log(b); // Salida: 4

[a = 40, b = 4] = [1, 23];
console.log(a); // Salida: 1
console.log(b); // Salida: 23</code></pre><figcaption>Valor por defecto</figcaption></figure><p>Los valores por defecto también pueden referirse a otras variables, incluida la del mismo literal del arreglo.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let [first = "Cotlin", second = first] = [];
console.log(first); // Salida: Cotlin
console.log(second); // Salida: Cotlin

let [first = "Cotlin", second = first] = ["Koku"];
console.log(first); // Salida: Koku
console.log(second); // Salida: Koku

let [first = "Cotlin", second = first] = ["Koku", "Lydia"];
console.log(first); // Salida: Koku
console.log(second); // Salida: Lydia</code></pre><figcaption>Valores por defecto</figcaption></figure><h3 id="ignorar-algunos-valores">Ignorar algunos valores</h3><p>La desestructuración permite asignar una variable a los elementos que le interesan. Puede ignorar u omitir los demás elementos del arreglo usando comas al final.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let a, b;
[a, , b] = ["Señor", "Corona", "Rosas"];

console.log(a); // Salida: Señor
console.log(b); // Salida: Rosas</code></pre><figcaption>Ignorar valores</figcaption></figure><h3 id="el-par-metro-rest-y-la-sintaxis-spread">El parámetro Rest y la sintaxis Spread</h3><p><em>El nuevo operador (...)</em> que se añadió en ES6 puede utilizarse en la desestructuración. Si el operador (...) aparece a la izquierda en la desestructuración, se trata de un <strong><a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Functions/rest_parameters">PARÁMETRO REST</a></strong>. Un parámetro Rest se utiliza para mapear todos los elementos restantes del arreglo que no han sido mapeados a la propia variable Rest. Es como recoger lo que queda. La variable Rest debe ser siempre la última, de lo contrario se produce un <code>SyntaxError</code>.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let planetas = ["Mercurio", "Tierra", "Venus", "Marte", "Pluton", "Saturno"];
let [primero, tercero, ...otros] = planetas;

console.log(primero); // Salida: Mercurio
console.log(tercero); // Salida: Venus
console.log(otros); // Salida: ["Marte", "Pluton", "Saturno"]</code></pre><figcaption>Parámetro Rest</figcaption></figure><p>Si el operador (...) aparece a la derecha en la desestructuración, se trata de un <a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Operators/Spread_syntax"><strong>SINTAXIS SPREAD</strong></a>. Toma todos los demás elementos del arreglo que no tienen ninguna variable asignada y la asigna a la variable restante.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let planetas = ["Venus", "Marte", "Pluton", "Saturno"];

let [primero, segundo, ...rest] = ["Mercurio", "Tierra", ...planetas, "Neptuno"];

console.log(primero); // Salida: Mercurio
console.log(segundo); // Salida: Tierra
console.log(rest); // Salida: [ 'Venus', 'Marte', 'Pluton', 'Saturno', 'Neptuno']</code></pre><figcaption>Sintaxis Spread</figcaption></figure><p>Cuando puedes tener más variables en el lado izquierdo, mapea los elementos individuales del arreglo igualmente a las variables.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let planetas = ["Mercurio", "Tierra", "Venus", "Marte", "Pluton", "Saturn"];

let [uno, dos, ...rest] = ["Mercurio", ...planets];

console.log(uno); // Salida: Mercurio
console.log(dos); // Salida: Mercurio
console.log(rest); // Salida: ["Tierra", "Venus", "Marte", "Pluton", "Saturno"]

planets = ["Mercurio", "Tierra", "Venus", "Marte", "Pluton", "Saturno"];

let [primero, segundo, tercero, cuarto, ...rest] = ["Mercurio", "Tierra", ...planetas];

console.log(primero); // Salida: Mercurio
console.log(segundo); // Salida: Tierra
console.log(tercero); // Salida: Mercurio
console.log(cuarto); // Salida: Tierra
console.log(rest); // Salida: ["Venus", "Marte", "Pluton", "Saturno"]</code></pre><figcaption>Mapear elementos de un arreglo</figcaption></figure><h3 id="intercambio-de-variables"><strong>Intercambio de variables</strong></h3><p>Una desestructuración puede emplearse para intercambiar los valores de dos variables.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let a, b;
[a, b] = ["Hombre", "Mujer"];
[a, b] = [b, a];

console.log(a); // Salida: Mujer
console.log(b); // Salida: Hombre</code></pre><figcaption>Intercambio de valores en variables</figcaption></figure><h3 id="desestructuraci-n-de-arreglos-anidados"><strong>Desestructuración de arreglos anidados</strong></h3><p>También puede realizar la desestructuración anidada con arreglos. El elemento correspondiente debe ser un arreglo para poder usar un literal de arreglo con desestructuración anidada para asignar elementos de la misma a variables locales.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let numeros = [8, [1, 2, 3], 10, 12];
let [a, [d, e, f]] = numeros;

console.log(a); // Salida: 8
console.log(d); // Salida: 1
console.log(e); // Salida: 2</code></pre><figcaption>Arreglos anidados y desestructuración</figcaption></figure><h3 id="desestructuraci-n-de-m-ltiples-arreglos">Desestructuración de múltiples arreglos</h3><p>Puede desestructurar un arreglo más de una vez en el mismo fragmento de código.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let lugares = ["primero", "segundo", "tercero", "cuarto"];
let [a, b, , d] = [f, ...rest] = lugares;

console.log(a); // Salida: primero
console.log(d); // Salida: cuarto
console.log(f); // Salida: primero
console.log(rest); // Salida: ["segundo", "tercero", "cuarto"]</code></pre><figcaption>Desestruturación con múltiples arreglos</figcaption></figure><h3 id="conclusi-n"><strong>Conclusión</strong></h3><p>Puede copiar y pegar el código en el <a href="https://babeljs.io/repl#?browsers=defaults%2C%20not%20ie%2011%2C%20not%20ie_mob%2011&amp;build=&amp;builtIns=false&amp;corejs=3.21&amp;spec=true&amp;loose=true&amp;code_lz=DYUwLgBMCuDmCGAnEBnCBeCBtARAB0QEsBbERAexwBoIcURZoA7AE0ppzDIGMz3bu0JGEoBdANwAoUJCzwaAIxo0WojNgBmNAHS7kKMGswwE-qZO7kmKcqG3BysABTwAlOIgB6TxADK8YEIWeAAuCAISPgsrGzsHZxZ3Lx9_QOCwwWFyaOtbEHtHJw0k7z8AoNDwolIKHNj8-Kd9MBKU8vTsOgZmNmpaLkReCj6cTMQRHFEgA&amp;debug=false&amp;forceAllTransforms=true&amp;modules=false&amp;shippedProposals=true&amp;circleciRepo=&amp;evaluate=true&amp;fileSize=true&amp;timeTravel=true&amp;sourceType=module&amp;lineWrap=true&amp;presets=env%2Creact%2Cstage-2&amp;prettier=true&amp;targets=Node-10.13&amp;version=7.21.9&amp;externalPlugins=&amp;assumptions=%7B%7D">sitio web de Babel</a> para ver cómo sería el código si no existiera la desestructuración. Habrías escrito más líneas de código, pero la desestructuración lo simplifica todo.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Cómo crear una presentación de diapositivas con HTML, CSS y JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ Una presentación de diapositivas es una secuencia de imágenes o texto que consiste en mostrar un elemento de la secuencia en un intervalo de tiempo determinado. En este tutorial puedes crear una secuencia de diapositivas siguiendo estos sencillos pasos: Escriba en el HTML   <!DOCTYPE html>   <html ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/como-crear-una-presentacion-de-diapositivas-con-html-css-y-javascript/</link>
                <guid isPermaLink="false">646bf1d1a7154006ea79e27d</guid>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Santiago Toquica Yanguas ]]>
                </dc:creator>
                <pubDate>Sun, 11 Jun 2023 00:15:56 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2023/06/5f9c9e44740569d1a4ca3c37.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-create-a-slideshow/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Create a Slideshow with HTML, CSS, and JavaScript</a>
      </p><p>Una presentación de diapositivas es una secuencia de imágenes o texto que consiste en mostrar un elemento de la secuencia en un intervalo de tiempo determinado.</p><p>En este tutorial puedes crear una secuencia de diapositivas siguiendo estos sencillos pasos:</p><h3 id="escriba-en-el-html">Escriba en el HTML</h3><figure class="kg-card kg-code-card"><pre><code class="language-html">  &lt;!DOCTYPE html&gt;
  &lt;html lang="en"&gt;
    &lt;head&gt;
      &lt;meta charset="UTF-8"&gt;
      &lt;title&gt;Slideshow&lt;/title&gt;
      &lt;link rel="stylesheet" href="style.css"&gt;
    &lt;/head&gt;
    &lt;body&gt;
      &lt;div id="slideshow-example" data-component="slideshow"&gt;
        &lt;div role="list"&gt;
          &lt;div class="slide"&gt;
            &lt;img src="" alt=""&gt;
          &lt;/div&gt;
          &lt;div class="slide"&gt;
            &lt;img src="" alt=""&gt;
          &lt;/div&gt;
          &lt;div class="slide"&gt;
            &lt;img src="" alt=""&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;script src="slideshow.js"&gt;&lt;/script&gt;
    &lt;/body&gt;
  &lt;/html&gt;</code></pre><figcaption>index.html</figcaption></figure><h2 id="escribir-estilos-para-ocultar-diapositivas-y-mostrar-solo-una-diapositiva-">Escribir estilos para ocultar diapositivas y mostrar solo una diapositiva.</h2><p>Para ocultar las diapositivas tienes que darles un estilo por defecto. Esto indicará que solo muestres una diapositiva si está activa o si quieres mostrarla.</p><figure class="kg-card kg-code-card"><pre><code class="language-css">  [data-component="slideshow"] .slide {
    display: none;
  }

  [data-component="slideshow"] .slide.active {
    display: block;
  }</code></pre><figcaption>styles.css - CSS con esitlos para mostrar una diapostiva y estilo por default</figcaption></figure><h2 id="cambia-las-diapositivas-en-un-intervalo-de-tiempo-">Cambia las diapositivas en un intervalo de tiempo.</h2><p>El primer paso para cambiar las diapositivas que se muestran es seleccionar el componente padre de las diapositivas y luego sus diapositivas.</p><p>Cuando selecciones las diapositivas tienes que ir sobre cada diapositiva y añadir o quitar la clase <code>active</code> dependiendo de la diapositiva que quieras mostrar. Después solo tienes que repetir el proceso durante un intervalo de tiempo determinado.</p><p>Tenga en cuenta que cuando elimina una clase <code>active</code> de una diapositiva, la está ocultando debido a los estilos definidos en el paso anterior. Pero cuando añades una clase <code>active</code> a la diapositiva, estás sobrescribiendo el estilo <code>display:none a display:block</code>, en consecuencia la diapositiva se mostrará a los usuarios.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">  var slideshows = document.querySelectorAll('[data-component="slideshow"]');
  
  // Aplicar a todas las diapositivas que defina con la marca escrita
  slideshows.forEach(initSlideShow);

  function initSlideShow(slideshow) {

    var slides = document.querySelectorAll(`#${slideshow.id} [role="list"] .slide`); // Obtener una matriz de diapositivas

    var index = 0, time = 5000;
    slides[index].classList.add('active');  
    
    setInterval( () =&gt; {
      slides[index].classList.remove('active');
      
      // Recorre cada diapositiva incrementando el índice
      index++;
      
      // Si repasa todas las diapositivas, reinicie el índice para mostrar la primera diapositiva y volver a empezar
      if (index === slides.length) index = 0; 
      
      slides[index].classList.add('active');

    }, time);
  }</code></pre><figcaption>slideshow.js - Código fuente de Javascript</figcaption></figure><h3 id="ejemplo-de-codepen-siguiendo-este-tutorial"><a href="https://codepen.io/AndresUris/pen/rGXpvE">Ejemplo de Codepen siguiendo este tutorial</a></h3> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Cómo difuminar una imagen en Photoshop: difuminar caras, fondos y mucho más ]]>
                </title>
                <description>
                    <![CDATA[ Este tutorial le mostrará cómo desenfocar caras, fondos, texto y más, usando Photoshop CC. Vamos a hacer uso del efecto de desenfoque gaussiano. El primer paso es abrir la imagen que desea modificar en Photoshop CC. Cómo difuminar toda una imagen en Photoshop Si desea desenfocar toda la imagen, elija ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/como-difuminar-una-imagen-en-photoshop-difuminar-caras-fondos-y-mucho-mas/</link>
                <guid isPermaLink="false">646bd02aa7154006ea79e1d2</guid>
                
                    <category>
                        <![CDATA[ photoshop ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Santiago Toquica Yanguas ]]>
                </dc:creator>
                <pubDate>Sun, 11 Jun 2023 00:12:50 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2023/06/blur-face.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-blur-a-picture-in-photoshop-blur-faces-backgrounds-and-more/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Blur a Picture in Photoshop - Blur Faces, Backgrounds, and More</a>
      </p><p>Este tutorial le mostrará cómo desenfocar caras, fondos, texto y más, usando Photoshop CC.</p><p>Vamos a hacer uso del efecto de desenfoque gaussiano. El primer paso es abrir la imagen que desea modificar en Photoshop CC.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-151.png" class="kg-image" alt="image-151" width="600" height="400" loading="lazy"></figure><h3 id="c-mo-difuminar-toda-una-imagen-en-photoshop">Cómo difuminar toda una imagen en Photoshop</h3><p>Si desea desenfocar toda la imagen, elija <strong>Filtro &gt; Desenfocar &gt; Desenfoque Gaussiano...</strong></p><p>Ajusta el radio para añadir más o menos porcentaje de desenfoque a la imagen. A continuación, haz clic en "Aceptar".</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-155.png" class="kg-image" alt="image-155" width="600" height="400" loading="lazy"></figure><p>¡Has terminado!</p><h3 id="c-mo-difuminar-caras-en-photoshop-m-todo-f-cil-">Cómo difuminar caras en Photoshop (método fácil)</h3><p>Si quieres desenfocar una cara en Photoshop, aquí tienes una forma fácil de hacerlo. También puedes utilizar este método para difuminar textos, logotipos, fondos y cualquier otra cosa que desee difuminar.</p><p>En primer lugar, use las herramientas de selección para seleccionar el área que desea desenfocar. En el siguiente ejemplo, la cara se selecciona con la herramienta <strong>Marco elíptico</strong>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-156.png" class="kg-image" alt="image-156" width="600" height="400" loading="lazy"></figure><p>A continuación, aplica un Desenfoque gaussiano como antes <strong>(Filtro &gt; Desenfoque &gt; Desenfoque gaussiano...).</strong> &nbsp;Selecciona el radio y haz clic en "Aceptar". Por último, selecciona <strong>Seleccionar &gt; Deseleccionar.</strong></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-157.png" class="kg-image" alt="image-157" width="600" height="400" loading="lazy"></figure><p>¡Has terminado!</p><h3 id="c-mo-difuminar-caras-en-photoshop-m-todo-avanzado-">Cómo difuminar caras en Photoshop (método avanzado)</h3><p>En el anterior método fácil, hay una línea dura entre la sección desenfocada y la no desenfocada. Si desea hacer una transición suave entre las secciones, utilice este método avanzado. Este método también mantendrá la versión no desenfocada en una capa separada para que sea fácil revertirla si es necesario.</p><p>En primer lugar, duplique la capa haciendo clic con el botón derecho en la capa y seleccionando "<strong>Duplicar capa...</strong>".</p><p>A continuación, aplique un desenfoque gaussiano como antes <strong>(Filtro &gt; Desenfocar &gt; Desenfoque Gaussiano...)</strong> con el radio que desee.</p><p>Añada una máscara de capa a la capa duplicada haciendo clic en el botón <strong>"Añadir máscara vectorial"</strong>. Asegúrese de mantener pulsado OPTION en Mac o ALT en Windows mientras hace clic en el botón para ocultar toda la capa detrás de la máscara. Ya no verá la capa borrosa.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-159.png" class="kg-image" alt="image-159" width="600" height="400" loading="lazy"></figure><p>El siguiente paso es utilizar una herramienta de pincel para pintar las zonas que quieres difuminar. Asegúrese de que la herramienta pincel tiene un borde suave (considere ajustar la dureza al 0%) y utilice el blanco como color de primer plano.</p><p>Cuando pintes de blanco sobre la máscara, las zonas que pintes se volverán borrosas, porque la capa borrosa queda al descubierto.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/09/image-160.png" class="kg-image" alt="image-160" width="600" height="400" loading="lazy"></figure><p>Puedes ver en la imagen de arriba que la capa original sin desenfocar sigue disponible.</p><p>Puedes seguir pintando cualquier sección que quieras desenfocar.</p><p>¡Has terminado!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ El menú de inicio de Windows 10 no funciona (resuelto) ]]>
                </title>
                <description>
                    <![CDATA[ Artículo original escrito por Kris Koishigawa [https://www.freecodecamp.org/news/author/kris/] Artículo original Windows 10 Start Menu Not Working (Solved) [https://www.freecodecamp.org/news/windows-10-start-menu-not-working-solved/] Traducido y adaptado por Santiago Yanguas [https://twitter.com/ToqYang] Windows 10 ha recorrido un largo camino desde su lanzamiento en 2015. Cada actualización trae un montón de nuevas características, y Microsoft ha abrazado a la ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/el-menu-de-inicio-de-windows-10-no-funciona/</link>
                <guid isPermaLink="false">61ff2d90e56f6e08aa1c5561</guid>
                
                    <category>
                        <![CDATA[ windows ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Santiago Toquica Yanguas ]]>
                </dc:creator>
                <pubDate>Mon, 14 Feb 2022 14:44:10 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2022/02/5fa1226549c47664ed819287.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><strong>Artículo original escrito por </strong><a href="https://www.freecodecamp.org/news/author/kris/">Kris Koishigawa</a><br><strong>Artículo original </strong><a href="https://www.freecodecamp.org/news/windows-10-start-menu-not-working-solved/">Windows 10 Start Menu Not Working (Solved)</a><br><strong>Traducido y adaptado por </strong><a href="https://twitter.com/ToqYang">Santiago Yanguas</a></p><p>Windows 10 ha recorrido un largo camino desde su lanzamiento en 2015. Cada actualización trae un montón de nuevas características, y Microsoft ha abrazado a la comunidad de código abierto de una manera que antes se creía imposible.</p><p>Aun así, como con cualquier sistema operativo, hay errores. Y uno de los errores más comunes a los que se han enfrentado los usuarios de Windows 10 es que el menú de inicio deja de funcionar de repente.</p><p>A veces el menú de inicio abierto se congela, no responde y otras veces no se abre en absoluto cuando se hace clic en el botón del menú de inicio.</p><p>Sea cual sea el problema específico que tengas con el menú de inicio de Windows 10, en este artículo repasaremos algunas soluciones rápidas y no tan rápidas.</p><h2 id="c-mo-reiniciar-el-explorador-de-windows">Cómo reiniciar el Explorador de Windows</h2><p>El Explorador de Windows, que ahora se llama explorador de archivos, es la aplicación que se utiliza para navegar por el sistema de archivos y abrir programas y archivos. Pero también controla cosas como el Menú Inicio, la barra de tareas y otras aplicaciones.</p><p>Si tienes un problema con el menú de inicio, lo primero que puedes intentar hacer es reiniciar el proceso "Explorador de Windows" en el administrador de tareas.</p><p>Para abrir el administrador de Tareas, pulsa <strong>Ctrl + Alt + Delete</strong>, y luego haz clic en el botón "Administrador de Tareas".</p><p>Haz clic en "más detalles" para ver una lista completa de los programas abiertos y los procesos en segundo plano que estás ejecutando:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/11/task-manager-more-details.jpg" class="kg-image" alt="task-manager-more-details" width="600" height="400" loading="lazy"></figure><p>Desplázate por la lista hasta encontrar el proceso "Explorador de Windows". A continuación, haz clic con el botón derecho en "Explorador de Windows" y selecciona "Reiniciar":</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/11/task-manager-restart-windows-explorer.jpg" class="kg-image" alt="task-manager-restart-windows-explorer" width="600" height="400" loading="lazy"></figure><p>Habré un breve destello mientras Windows reinicia el Explorador/Finder de Windows, junto con la barra de tareas y el Menú Inicio.</p><p>Después de eso, intenta abrir el Menú Inicio. Si sigue sin funcionar con normalidad, intenta una de las otras correcciones que aparecen a continuación.</p><h2 id="c-mo-reparar-archivos-de-sistema-de-windows-corruptos-o-perdidos">Cómo reparar archivos de sistema de Windows corruptos o perdidos</h2><p>A veces, una actualización sale mal o se borra accidentalmente un archivo importante mientras se escarba en el sistema de archivos.</p><p>Si el menú de inicio sigue dando problemas o si otras aplicaciones principales de Windows se bloquean, puedes intentar restaurar los archivos de sistema de Windows que falten o estén dañados.</p><p>Para ello, tendrás que <a href="https://www.freecodecamp.org/news/how-to-open-the-command-prompt-in-windows-10/#how-to-open-command-prompt-as-an-administrator">abrir el símbolo del sistema de Windows como administrador</a> y ejecutar el programa Comprobador de Archivos del Sistema.</p><p>Una vez que abras el Símbolo del sistema como administrador, ejecuta el comando <code>sfc /scannow</code>:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/11/sfc-scannow.jpg" class="kg-image" alt="sfc-scannow" width="600" height="400" loading="lazy"></figure><p>Comprobador de Archivos del Sistema comenzará a revisar todos los archivos de tu sistema y reemplazará cualquier archivo corrupto o faltante con una copia en caché.</p><p>Este proceso puede tardar un poco, así que siéntate libre de hacer otra cosa durante 5-10 minutos. Sólo ten cuidado de no cerrar la ventana mientras <code>sfc</code> está haciendo trabajo.</p><p>Una vez que el Comprobador de Archivos del Sistema haya terminado, verás un informe de todos los archivos que ha reemplazado o si todo estaba bien, verás un mensaje como este:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/11/sfc-scan-complete.jpg" class="kg-image" alt="sfc-scan-complete" width="600" height="400" loading="lazy"></figure><p>Si el comprobador de Archivos de Sistema reemplazó algún archivo de sistema corrupto o faltante, guarda todo tu trabajo abierto y reinicia tu computadora. Una vez que vuelvas a iniciar la sesión, intenta abrir el menú de inicio para ver si se han solucionado los problemas.</p><p><strong>Nota:</strong> También puedes utilizar Powershell para ejecutar el comando <code>sfc /scannow</code>, pero recuerda que tendrás que abrir un terminal elevado de Powershell.</p><h2 id="c-mo-restablecer-el-men-de-inicio-con-las-aplicaciones-predeterminadas-de-windows-10">Cómo restablecer el menú de inicio con las aplicaciones predeterminadas de Windows 10</h2><p>Lo siguiente que puedes probar es restablecer el menú de inicio por completo, junto con todas las aplicaciones de Windows 10 que estaban preinstaladas o instaladas desde la Microsoft Store.</p><p>Para ello, tendrás que abrir PowerShell como administrador - el Símbolo del sistema no funcionará para el comando que vas a ejecutar.</p><p>Hay muchas formas de abrir PowerShell, pero una de las más rápidas es utilizar el programa Run.</p><p>Utiliza el atajo de teclado <strong>Windows + R</strong> para abrir el programa Ejecutar, introduce "powershell", luego mantén pulsado "Ctrl + Shift" y haz clic en el botón "OK":</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/11/run-cmd-powershell.jpg" class="kg-image" alt="run-cmd-powershell" width="600" height="400" loading="lazy"></figure><p>Esto debería abrir una terminal de PowerShell con privilegios administrativos.</p><p>En el terminal de PowerShell, ejecuta el siguiente comando:</p><pre><code>Get-AppXPackage -AllUsers | Foreach {Add-AppxPackage -DisableDevelopmentMode -Register "$($_.InstallLocation)\AppXManifest.xml"}
</code></pre><p>El comando <code>Get-AppXPackage</code> intentará reinstalar todas las aplicaciones por defecto de Windows, incluyendo el menú de inicio y la barra de búsqueda.</p><p>También registrará un archivo de manifiesto para cada programa que reinstales. Sin embargo, no tienes que preocuparte por los archivos de manifiesto: es algo que Windows necesita para ejecutar cada programa.</p><p>Dale 5-10 minutos, y asegúrate de no cerrar la ventana de PowerShell hasta que haya terminado.</p><p><strong>Nota:</strong> Es posible que aparezcan algunos errores de aspecto aterrador mientras se ejecuta el comando <code>Get-AppXPackage</code>. No te preocupes por ellos - la mayoría son sólo advertencias acerca de por qué un programa no puede ser reinstalado:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/11/powershell-get-appxpackage.jpg" class="kg-image" alt="powershell-get-appxpackage" width="600" height="400" loading="lazy"></figure><p>Cuando el comando <code>Get-AppXPackage</code> haya terminado, reinicia tu ordenador, inicia sesión e intenta abrir el Menú de Inicio.</p><h2 id="c-mo-restablecer-la-instalaci-n-de-windows-10">Cómo restablecer la instalación de Windows 10</h2><p>Si ninguno de los métodos anteriores arregló el Menú de Inicio, lo último que puedes probar es hacer un restablecimiento de fábrica de tu instalación de Windows 10. Pero ten en cuenta que este es un método "casi de tierra quemada" y sólo debe ser utilizado como último recurso.</p><p>El restablecimiento de la instalación de Windows 10 debería mantener intactos todos tus archivos personales (documentos, imágenes, vídeos, etc.), pero desinstalará todos los demás controladores y programas que hayas instalado. Básicamente, esto restablece tu ordenador al estado en el que estaba cuando lo encendiste por primera vez.</p><p>Antes de seguir adelante, haz copias de seguridad de todos tus archivos importantes utilizando una unidad flash, un disco duro/SSD externo y/o un alojamiento de archivos en línea como Google Drive o Dropbox.</p><p>De hecho, haz dos copias de seguridad. Probablemente, no las necesites, pero no está de más.</p><p>Cuando hayas terminado de hacer la copia de seguridad de todos tus archivos, abre un terminal de PowerShell: utiliza el atajo de teclado de <strong>Windows + R</strong>, introduce "powershell" y haz clic en el botón "Aceptar".</p><p>En el terminal de PowerShell, ejecuta el comando <code>systemreset</code> para que aparezca el asistente de restablecimiento de Windows.</p><p>A continuación, haz clic en el botón Keep my files("Conservar mis archivos"):</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2020/11/system-reset-keep-my-files.jpg" class="kg-image" alt="system-reset-keep-my-files" width="600" height="400" loading="lazy"></figure><p>Espera un momento mientras el asistente analiza tu sistema. Entonces, verás una lista de todos los programas que se eliminarán:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2020/11/system-reset-programs-to-be-removed.jpg" class="kg-image" alt="system-reset-programs-to-be-removed" width="600" height="400" loading="lazy"></figure><p>Haz clic en el botón "Siguiente" y sigue las instrucciones para restablecer la instalación de Windows 10.</p><p>Una vez que hayas terminado de restablecer Windows y de crear un nuevo usuario, el Menú de Inicio debería volver a funcionar.</p><h2 id="cortana-abre-el-men-de-inicio">"Cortana, abre el menú de inicio"</h2><p>Así que esas son todas las formas de arreglar el menú de inicio de Windows 10, listadas de la más fácil a la más difícil.</p><p>¿Te ha funcionado alguno de estos métodos? ¿Hay alguna otra forma de abrir el Menú Inicio que me haya perdido? Házmelo saber en <a href="https://twitter.com/kriskoishigawa">Twitter</a>.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Cómo instalar las herramientas de línea de comandos de Xcode en un Mac ]]>
                </title>
                <description>
                    <![CDATA[ Artículo original escrito por Daniel Kehoe [https://www.freecodecamp.org/news/author/danielkehoe/]  [https://www.freecodecamp.org/news/author/thanoshan/] Artículo original How to Install Xcode Command Line Tools on a Mac [https://www.freecodecamp.org/news/install-xcode-command-line-tools/] Traducido y adaptado por Santiago Yanguas [https://twitter.com/ToqYang] Los desarrolladores deben instalar Xcode Command Line Tools antes de poder desarrollar software en un Mac. Apple proporciona un entorno ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/como-instalar-las-herramientas-de-linea-de-comandos-xcode-en-un-mac/</link>
                <guid isPermaLink="false">61ff13f0e56f6e08aa1c5426</guid>
                
                    <category>
                        <![CDATA[ Desarrollo de Software ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Santiago Toquica Yanguas ]]>
                </dc:creator>
                <pubDate>Sun, 13 Feb 2022 02:55:40 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2022/02/Terminal_Mac.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><strong>Artículo original escrito por </strong><a href="https://www.freecodecamp.org/news/author/danielkehoe/">Daniel Kehoe </a><a href="https://www.freecodecamp.org/news/author/thanoshan/"> </a><br><strong>Artículo original </strong><a href="https://www.freecodecamp.org/news/install-xcode-command-line-tools/">How to Install Xcode Command Line Tools on a Mac</a><br><strong>Traducido y adaptado por </strong><a href="https://twitter.com/ToqYang">Santiago Yanguas</a></p><p>Los desarrolladores deben instalar Xcode Command Line Tools antes de poder desarrollar software en un Mac.</p><p>Apple proporciona un entorno de desarrollo completo para programadores llamado Xcode. Si está desarrollando software para macOS, iOS, tvOS y watchOS, debe instalar la aplicación Xcode completa.</p><p>No está preinstalado, pero puedes instalarlo desde el sitio web para <a href="https://developer.apple.com/download/">desarrolladores de Apple</a> o desde la App Store de tu Mac.</p><h2 id="-qu-es-xcode-command-line-tools">¿Qué es Xcode Command Line Tools?</h2><p>Si no estás desarrollando software para un dispositivo Apple, no necesitarás la aplicación completa de Xcode (¡requiere más de 40 GB de espacio en disco!).</p><p>En su lugar, instalarás Xcode Command Line Tools. Es un paquete más pequeño para desarrolladores de software con herramientas que se ejecutan en la línea de comandos, es decir, en la aplicación Terminal.</p><p>Los programadores han utilizado estas herramientas en los sistemas operativos Unix desde los inicios de la informática, y son la base de casi todo el desarrollo de software.</p><p>Por suerte, el paquete de herramientas de Xcode Command Line Tools sólo requiere 1,2 GB de espacio en el disco.</p><p>Tienes tres opciones para instalar Xcode Command Line Tools en un Mac:</p><ul><li>Instalar el paquete completo de Xcode.</li><li>Instalar las herramientas de línea de comandos de Xcode cuando se activan mediante un comando.</li><li>Instalar Xcode Command Line Tools como parte de una instalación Homebrew.</li></ul><p>No recomiendo instalar el paquete completo de Xcode a menos que estés desarrollando software para un dispositivo Apple. La descarga tardará demasiado y consumirá espacio innecesario en el disco. En su lugar, prueba cualquiera de los dos métodos más rápidos.</p><h2 id="c-mo-instalar-xcode-command-line-tools-desde-l-nea-de-comandos">Cómo instalar Xcode Command Line Tools desde línea de comandos</h2><p>Apple ha facilitado la instalación de Xcode Command Line Tools, ya que ciertos comandos le pedirán que inicie la instalación.</p><p>Aquí hay ejemplos de comandos que desencadenarán un aviso para instalar Xcode Command Line Tools:</p><ul><li><code>clang</code> – Un compilador que convierte el código fuente en un programa ejecutable.</li><li><code>gcc</code> – El compilador de GNU.</li><li><code>git</code> – El sistema de control de versiones "save-as-you-go".</li></ul><p>Ejecutando cualquiera de estos comandos en la terminal aparecerá un aviso para instalar Xcode Command Line Tools. He escrito en otra parte sobre <a href="https://mac.install.guide/terminal/index.html">Cómo abrir la Terminal en MacOS</a> - sólo haga clic en el icono de Spotlight en la barra de menú y escriba "terminal".</p><p>También puedes introducir el comando <code>xcode-select --install</code> en el terminal para comenzar el proceso de instalación. Verás un panel que te pide que instales Xcode Command Line Tools.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://mac.install.guide/assets/images/ruby/install-Xcode-CLT.png" class="kg-image" alt="install-Xcode-CLT" width="573" height="307" loading="lazy"></figure><p>Has clic en "Instalar" para comenzar el proceso de descarga e instalación.</p><figure class="kg-card kg-image-card"><img src="https://mac.install.guide/assets/images/ruby/install-Xcode-CLT-progress.png" class="kg-image" alt="install-Xcode-CLT-progress" width="566" height="230" loading="lazy"></figure><p>La instalación tarda 8 minutos en un Mac M1 Mini 2021, con una conexión a Internet de 100Mbps. Es significativamente más lenta en Mac Intel con una conexión a Internet lenta.</p><figure class="kg-card kg-image-card"><img src="https://mac.install.guide/assets/images/ruby/install-Xcode-CLT-done.png" class="kg-image" alt="install-Xcode-CLT-done" width="566" height="200" loading="lazy"></figure><p>Verás un mensaje de confirmación cuando se complete la instalación.</p><p>Comprueba que haya instalado correctamente las herramientas de línea de comandos de Xcode:</p><pre><code class="language-bash">$ xcode-select -p
</code></pre><p>Deberías ver lo siguiente:</p><pre><code class="language-bash">/Library/Developer/CommandLineTools
</code></pre><h2 id="c-mo-usar-homebrew-para-instalar-xcode-command-line-tools">Cómo usar Homebrew para instalar Xcode Command Line Tools</h2><p>Aunque es fácil usar la línea de comandos para instalar Xcode Command Line Tools, recomiendo un método aún más fácil: usar Homebrew.</p><p>Esta opción se ha añadido recientemente a Homebrew, por lo que muchos desarrolladores no la conocen.</p><p>Homebrew es el popular gestor de paquetes de Mac. La mayoría de los desarrolladores necesitan lenguajes de programación y utilidades que no vienen instaladas en macOS, que no están incluidas en el paquete de herramientas de línea de comandos de Xcode. Homebrew puede instalar casi cualquier herramienta de código abierto para desarrolladores.</p><p>Ya que probablemente necesitarás Homebrew, también puedes dejar que Homebrew instale Xcode Command Line Tools por ti.</p><p>Primero, comprueba si Homebrew ya está instalado.</p><pre><code class="language-bash">$ brew
</code></pre><p>Si Homebrew no está instalado, verás:</p><pre><code class="language-bash">zsh: command not found: brew
</code></pre><p>Homebrew proporciona un script de instalación que puedes ejecutar con un solo comando (comprueba que no ha cambiado en el <a href="https://brew.sh/">sitio de Homebrew</a>).</p><pre><code class="language-bash">$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
</code></pre><p>El script de instalación de Homebrew te pedirá que introduzcas tu contraseña de usuario de Mac. Esta es la contraseña que utilizas para iniciar sesión en tu Mac.</p><pre><code class="language-bash">Password:
</code></pre><p>No verás los caracteres mientras escribes. Pulsa return cuando hayas terminado.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://mac.install.guide/assets/images/ruby/homebrew-enter-password.png" class="kg-image" alt="homebrew-enter-password" width="697" height="245" loading="lazy"></figure><p>Si aún no has instalado Xcode Command Line Tools, verás un mensaje que dice "Se instalará Xcode Command Line Tools". Pulsa return para continuar cuando te lo pida el script de instalación de Homebrew.</p><figure class="kg-card kg-image-card"><img src="https://mac.install.guide/assets/images/ruby/install-homebrew.png" class="kg-image" alt="install-homebrew" width="697" height="525" loading="lazy"></figure><p>Verás mensajes de diagnóstico y de progreso. La instalación de Homebrew tarda de 2 a 15 minutos en un Mac M1 Mini 2021, con una conexión a Internet de 100Mbps. Es significativamente más lento en Mac Intel con una conexión de Internet lenta.</p><figure class="kg-card kg-image-card"><img src="https://mac.install.guide/assets/images/ruby/homebrew-complete.png" class="kg-image" alt="homebrew-complete" width="653" height="355" loading="lazy"></figure><p>En las máquinas Mac Intel, eso es todo lo que hay que hacer: Homebrew está listo para ser utilizado. En Mac Intel, Homebrew se instala en el directorio <code>/usr/local/bin</code>, que ya está configurado para el acceso del shell con el <code>$PATH</code> por defecto de macOS.</p><p>En las máquinas Apple Silicon, hay un paso más. Los archivos de Homebrew se instalan en la carpeta <code>/opt/homebrew</code>. Pero la carpeta no forma parte del <code>$PATH</code> por defecto. Sigue el consejo de Homebrew y crea un archivo <code>~/.zprofile</code> que contenga un comando que configure Homebrew. Homebrew muestra las instrucciones al final del proceso de instalación:</p><pre><code class="language-bash">- Add Homebrew to your PATH in ~/.zprofile:
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' &gt;&gt; ~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"
</code></pre><p>Una vez que hayas instalado Homebrew, comprueba que se ha instalado correctamente.</p><pre><code class="language-bash">$ brew doctor
</code></pre><p>Deberías ver esto:</p><pre><code class="language-bash">Your system is ready to brew.
</code></pre><p>Si Homebrew se instala correctamente, habrá archivos Homebrew en <code>/usr/local</code> (para macOS Intel) o <code>/opt/homebrew</code> (para Apple Silicon).</p><p>Ahora ya tienes instalados tanto Xcode Command Line Tools como Homebrew. </p><h2 id="tu-entorno-de-desarrollo">Tu entorno de desarrollo</h2><p>MacOS es la plataforma más popular para el desarrollo de software porque el sistema operativo está basado en Unix, el estándar de desarrollo de software desde hace mucho tiempo.</p><p>Con Xcode Command Line Tools instaladas, tendrás una base sólida para añadir casi cualquier herramienta de desarrollo de código abierto.</p><p>Añade Homebrew y tendrás un gestor de paquetes que puede instalar gestores de versiones, lenguajes de programación y casi cualquier otra herramienta que puedas necesitar.</p><p>Combinado con un editor de texto y una aplicación de terminal, estarás preparado para cualquier tutorial que encuentres en freeCodeCamp.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ cmd eliminar carpeta: Cómo eliminar archivos y carpetas en Windows ]]>
                </title>
                <description>
                    <![CDATA[ Artículo original escrito por Kris Koishigawa [https://www.freecodecamp.org/news/author/kris/]  [https://www.freecodecamp.org/news/author/thanoshan/] Artículo original cmd Delete Folder – How to Remove Files and Folders in Windows [https://www.freecodecamp.org/news/cmd-delete-folder-how-to-remove-files-and-folders-in-windows/] Traducido y adaptado por Santiago Yanguas [https://twitter.com/ToqYang] A veces es más rápido hacer las tareas con la línea de comandos. En este rápido tutorial repasare ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/cmd-eleminar-carpeta-como-eliminar-archivos-y-carpeta-en-windows/</link>
                <guid isPermaLink="false">61ff0554e56f6e08aa1c5340</guid>
                
                    <category>
                        <![CDATA[ Windows 10 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Santiago Toquica Yanguas ]]>
                </dc:creator>
                <pubDate>Sun, 13 Feb 2022 02:43:31 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2022/02/5fc9bc71e6787e098393991d.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><strong>Artículo original escrito por </strong><a href="https://www.freecodecamp.org/news/author/kris/">Kris Koishigawa</a><a href="https://www.freecodecamp.org/news/author/thanoshan/"> </a><br><strong>Artículo original </strong><a href="https://www.freecodecamp.org/news/cmd-delete-folder-how-to-remove-files-and-folders-in-windows/">cmd Delete Folder – How to Remove Files and Folders in Windows</a><br><strong>Traducido y adaptado por </strong><a href="https://twitter.com/ToqYang">Santiago Yanguas</a></p><p>A veces es más rápido hacer las tareas con la línea de comandos.</p><p>En este rápido tutorial repasaremos cómo abrir el Símbolo del sistema, algunos comandos básicos y banderas, y cómo eliminar archivos y carpetas en el Símbolo del sistema.</p><p>Si ya está familiarizado con los comandos básicos del DOS, no dudes en <a href="#c-mo-eliminar-archivos-con-el-comando-del">saltártelos</a>.</p><h2 id="c-mo-abrir-el-s-mbolo-del-sistema">Cómo abrir el símbolo del sistema</h2><p>Para abrir el símbolo del sistema, pulse la tecla de Windows y escriba "cmd".</p><p>A continuación, haga clic en "Ejecutar como administrador":</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/run-command-prompt-as-administrator.jpg" class="kg-image" alt="Screenshot showing how to open Command Prompt as an administrator" width="600" height="400" loading="lazy"><figcaption>Abrir CMD</figcaption></figure><p>Después de eso, verás una ventana de símbolo del sistema con privilegios administrativos: </p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/command-prompt-new-window.jpg" class="kg-image" alt="command-prompt-new-window" width="600" height="400" loading="lazy"><figcaption>Captura de pantalla de la ventana del símbolo del sistema</figcaption></figure><p>Si no puedes abrir el símbolo del sistema como administrador, no te preocupes. Puedes abrir una ventana normal del símbolo del sistema haciendo clic en "Open" en lugar de "Ejecutar como administrador".</p><p>La única diferencia es que es posible que no se pueda eliminar algunos archivos protegidos, lo que no debería ser un problema en la mayoría de los casos.</p><h2 id="c-mo-eliminar-archivos-con-el-comando-del">Cómo eliminar archivos con el comando <code>del</code></h2><p>Ahora que el símbolo del sistema está abierto, use <code>cd</code> para cambiar los directorios a donde están tus archivos.</p><p>He preparado un directorio en el escritorio llamado carpeta de pruebas. Puedes usar el comando <code>tree /f</code> para ver un, bueno, árbol, de todos los archivos y carpetas anidados:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/command-prompt-tree.jpg" class="kg-image" alt="Screenshot after running tree /f in target directory" width="600" height="400" loading="lazy"><figcaption>Arbol de directorios</figcaption></figure><p>Para eliminar un archivo, utiliza el siguiente comando: <code>del "&lt;filename&gt;"</code></p><p>Por ejemplo, para eliminar <code>Test file.txt</code>, basta con ejecutar <code>del "Test File.txt"</code>.</p><p>Es posible que aparezca un aviso preguntando si desea eliminar el archivo. Si es así, escriba "y" y pulse Intro.</p><p><strong>Nota:</strong> Cualquier archivo borrado con el comando <code>del</code> no puede ser recuperado. Ten mucho cuidado con dónde y cómo usas este comando.</p><p>Después de eso, puedes ejecutar <code>tree /f</code> para confirmar que tu archivo haya sido eliminado:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/del-tree-check.jpg" class="kg-image" alt="Screenshot after deleting file with del command" width="600" height="400" loading="lazy"><figcaption>Arbol de directorios con los cambios realizados</figcaption></figure><p>Además, un consejo extra: el símbolo del sistema tiene autocompletado básico. Así que puedes escribir <code>del Test</code>, pulsar la tecla de tabulación, y símbolo del sistema cambiará a <code>del "Test File.txt"</code>.</p><h3 id="c-mo-forzar-la-eliminaci-n-de-archivos-con-el-comando-del">Cómo forzar la eliminación de archivos con el comando <code>del</code></h3><p>A veces los archivos están marcados como de sólo lectura, y verás el siguiente error cuando intentes usar el comando <code>del</code>:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/read-only-error.jpg" class="kg-image" alt="Screenshot of error after trying to delete a read only file" width="600" height="400" loading="lazy"><figcaption>Intento de eliminar un archivo</figcaption></figure><p>Para evitarlo, utiliza el indicador <code>/f</code> para forzar la eliminación del archivo. Por ejemplo, <code>del /f "Read Only Test File.txt"</code>:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/del-force-flag.jpg" class="kg-image" alt="Screenshot after deleting file with the force flag" width="600" height="400" loading="lazy"><figcaption>Forzar eliminación de archivo</figcaption></figure><h2 id="c-mo-eliminar-carpetas-con-el-comando-rmdir">Cómo eliminar carpetas con el comando <code>rmdir</code></h2><p>Para borrar directorios/carpetas, necesitarás usar el comando <code>rmdir</code> o <code>rd</code>. Ambos comandos funcionan de la misma manera, pero vamos a seguir con <code>rmdir⁣, ya que</code> es un poco más expresivo.</p><p>Además, usaré los términos directorio y carpeta indistintamente durante el resto del tutorial. "Carpeta" es un término más reciente que se hizo popular con las primeras interfaces gráficas de escritorio, pero carpeta y directorio significan básicamente lo mismo.</p><p>Para eliminar un directorio, basta con utilizar el comando <code>rmdir &lt;directory name&gt;</code>.</p><p><strong>Nota:</strong> Cualquier directorio borrado con el comando <code>rmdir</code> no puede ser recuperado. Tenga mucho cuidado con dónde y cómo utiliza este comando.</p><p>En este caso quiero eliminar un directorio llamado Subfolder, así que usaré el comando <code>rmdir Subfolder</code>:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/directory-not-empty.jpg" class="kg-image" alt="Screenshot of a directory not empty error" width="600" height="400" loading="lazy"><figcaption>Comando para borrar directorios</figcaption></figure><p>Pero, si recuerdas antes, la Subfolder tienes un archivo en ella llamado <code>Nested Test File</code>.</p><p>Podrías entrar en el directorio de <code>Subfolder</code> con <code>cd</code> y eliminar el archivo, luego volver con <code>cd ..</code> y ejecutar el comando <code>rmdir Subfolder</code> de nuevo, pero eso sería tedioso. ¡E imagínate si hubiera un montón archivos y directorios anidados!</p><p>Al igual que con el comando <code>del</code>, hay una bandera útil que podemos utilizar para hacer las cosas mucho más rápido y más fácil.</p><h3 id="c-mo-utilizar-la-bandera-s-con-rmdir">Cómo utilizar la bandera <code>/s</code> con <code>rmdir</code></h3><p>Para eliminar un directorio, incluidos todos los archivos y subdirectorios anidados, basta con utilizar el indicador <code>/s</code>:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/rmdir-s-flag.jpg" class="kg-image" alt="Screenshot after running rmdir with the /s flag" width="600" height="400" loading="lazy"><figcaption>Remover directorio y mirar el arbol de directorios</figcaption></figure><p>Probablemente, aparecerá un aviso preguntando si quieres eliminar ese directorio. Si es así, escribe "y" y pulsa intro.</p><p>Y eso es todo. Eso debería ser todo lo que necesitas saber para eliminar archivos y carpetas en el símbolo del sistema de Windows.</p><p>Todos estos comandos deberían funcionar en PowerShell, que es básicamente la versión 2.0 de Command Prompt. Además, PowerShell tiene un montón de alias interesantes como <code>ls</code> y <code>clear</code> que deberían sentirse como en casa si estás familiarizado con la línea de comandos de Mac/Linux.</p><p>¿Te han ayudado estos comandos? ¿Hay otros comandos que te resulten útiles? En cualquier caso, házmelo saber a través de Twitter.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Fondo transparente: Opacidad de la imagen con CSS y HTML ]]>
                </title>
                <description>
                    <![CDATA[ Artículo original escrito por Kolade Chris [https://www.freecodecamp.org/news/author/kolade/] Artículo original Transparent Background – Image Opacity in CSS and HTML [https://www.freecodecamp.org/news/transparent-background-image-opacity-in-css-and-html/] Traducido y adaptado por Santiago Yanguas [https://twitter.com/ToqYang] Transparencia juega un papel importante en el desarrollo del front-end. Te permite elegir la transparencia de los elementos de tus páginas web. Puedes ajustar ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/fondo-transparente-opacidad-de-la-imagen-con-css-y-html/</link>
                <guid isPermaLink="false">61f3fba2e56f6e08aa1c3b6b</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Santiago Toquica Yanguas ]]>
                </dc:creator>
                <pubDate>Thu, 10 Feb 2022 20:16:18 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2022/02/frozen-bubble-1943224_1280.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><strong>Artículo original escrito por </strong><a href="https://www.freecodecamp.org/news/author/kolade/">Kolade Chris</a><br><strong>Artículo original </strong><a href="https://www.freecodecamp.org/news/transparent-background-image-opacity-in-css-and-html/">Transparent Background – Image Opacity in CSS and HTML</a><br><strong>Traducido y adaptado por </strong><a href="https://twitter.com/ToqYang">Santiago Yanguas</a></p><p>Transparencia juega un papel importante en el desarrollo del front-end. Te permite elegir la transparencia de los elementos de tus páginas web.</p><p>Puedes ajustar la transparencia de varias maneras - porque por supuesto, en CSS, hay múltiples maneras de hacer lo mismo.</p><p>La propiedad de <code>opacity</code> de CSS es la primera forma que puede venir a tu mente para cambiar la transparencia. Pero esta propiedad no puede venir al rescate todo el tiempo, especialmente cuando hay una imagen de fondo con texto en ella, que quieres hacer transparente.</p><p>Así que en este artículo, voy a mostrarte las distintas formas de ajustar la transparencia para que puedas empezar a implementarla en tus proyectos de código.</p><h2 id="transparencia-de-la-imagen-con-la-propiedad-css-opacity">Transparencia de la imagen con la propiedad CSS Opacity</h2><p>Para hacer que una imagen sea transparente, puedes utilizar la propiedad de <code>opacity</code> de CSS, como he mencionado anteriormente. La sintaxis básica de la propiedad opacity se muestra en el siguiente fragmento de código:</p><figure class="kg-card kg-code-card"><pre><code class="language-CSS">selector {
  opacity: value;
}
</code></pre><figcaption>Opacity</figcaption></figure><p>La propiedad opacidad toma valores de <code>0,0</code> a <code>1.0</code>, siendo <code>1</code> el valor por defecto para todos los elementos. Cuanto más bajo sea el valor, más transparente será. Así, si a un elemento se le da una opacidad de <code>0</code>, será invisible.</p><p>Puedes encontrar ejemplos de diferentes valores de opacidad en los siguientes fragmentos de código:</p><figure class="kg-card kg-code-card"><pre><code class="language-html">&lt;img src="freecodecamp.png" alt="freecodecamp-logo" /&gt;
</code></pre><figcaption>Logo</figcaption></figure><p>He añadido algo de CSS para centrar todo en la página:</p><figure class="kg-card kg-code-card"><pre><code class="language-css">body {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto;
  height: 100vh;
}


img {
  opacity: 1;
}
</code></pre><figcaption>Opacidad en la imagen</figcaption></figure><p>Un valor de opacidad de <code>1</code> es el predeterminado, por lo que la imagen aparece así:<br></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/09/default-opacity.png" class="kg-image" alt="default-opacity" width="600" height="400" loading="lazy"><figcaption>Opacidad de una imagen</figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-css">img {
  opacity: 0.5;
}
</code></pre><figcaption>Opacidad en 50%</figcaption></figure><p>Este código nos da un 50% de opacidad, puedes ver que el logo se ha desvanecido un poco:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/09/half-opacity.png" class="kg-image" alt="half-opacity" width="600" height="400" loading="lazy"><figcaption>Imagen con opacidad en 50%</figcaption></figure><pre><code class="language-css">img {
  opacity: 0;
}
</code></pre><p>Con una opacidad de <code>0</code>, la imagen es 100% transparente, por lo que se vuelve invisible:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/09/zero-opacity.png" class="kg-image" alt="zero-opacity" width="600" height="400" loading="lazy"></figure><p>La única forma de estar seguro de que la imagen está en la página es inspeccionarla con las devtools de tu navegador:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/09/image-in-devtools.jpg" class="kg-image" alt="image-in-devtools" width="600" height="400" loading="lazy"><figcaption>Imagen con opacidad en 0</figcaption></figure><p>Puedes usar este valor de opacidad para hacer muchas cosas - por ejemplo, puedes usarlo para incluir texto sobre una imagen heroica en un sitio web.</p><p>Tal vez te preguntes por qué querrías hacer invisible el contenido con un valor de opacidad de 0. Bueno, puede ser útil en animaciones, y en la construcción de juegos HTM + CSS + JavaScript también.</p><p>Definitivamente, querrás usar el posicionamiento CSS para ayudarte a alinear las cosas. Discutiré esto en las próximas partes del artículo.</p><h2 id="transparencia-de-la-imagen-de-fondo-en-html-y-css">Transparencia de la imagen de fondo en HTML y CSS</h2><p>CSS ofrece una forma de establecer la imagen de fondo para un elemento contenedor con la propiedad <code>background-image</code>, por lo que no tienes que hacerlo necesariamente con el CSS. Esto significa que también puedes colocar texto en el contenedor.</p><pre><code class="language-html">&lt;div class="showcase"&gt;
      &lt;h1&gt;A group of ring-tailed lemurs&lt;/h1&gt;
&lt;/div&gt;
</code></pre><pre><code class="language-css">body {
      display: flex;
      align-items: center;
      justify-content: center;
      margin: 0 auto;
      height: 100vh;
    }
    .showcase {
      background-image: url("ring-tailed-lemurs.jpeg");
      height: 400px;
      width: 500px;
      background-position: center;
      background-repeat: no-repeat;
      background-size: cover;
      opacity: 0.6;
    }
</code></pre><p>La desventaja de este enfoque es que la opacidad se establece para el contenedor donde están la imagen y el texto. Por lo tanto, la opacidad afecta también al texto, no sólo a la imagen. Esto probablemente no es lo que tú quieres.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/09/css-opacity.png" class="kg-image" alt="css-opacity" width="600" height="400" loading="lazy"></figure><h3 id="la-soluci-n">La solución</h3><p>Por defecto, cuando se aplica una opacidad a un contenedor, los descendientes la heredan también.</p><p>Una solución para esta situación es establecer la imagen de fondo en el HTML. Esto facilita la aplicación de la opacidad sólo a la imagen, en lugar de establecer la imagen de fondo para el contenedor en el CSS.</p><p>Esta vez, la imagen y el texto estarán separados, por lo que el texto no heredará el valor establecido para la <code>opacity</code>.</p><p>Esto significa que también hay que utilizar el posicionamiento CSS para alinear el texto dentro de la imagen.</p><pre><code class="language-html">&lt;div class="showcase"&gt;
   &lt;img src="ring-tailed-lemurs.jpeg" alt="lemurs" class="bg-image" /&gt;

   &lt;h1 class="bg-img-title"&gt;A group of ring-tailed lemurs&lt;/h1&gt;
&lt;/div&gt;
</code></pre><figure class="kg-card kg-code-card"><pre><code class="language-CSS">body {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto;
  height: 100vh;
}
.showcase {
  position: relative;
}

.bg-image {
  opacity: 0.7;
}

.bg-img-title {
  position: absolute;
  top: 420px;
  left: 20px;
}
</code></pre><figcaption>Opacidad al fondo, osea la imagen en el HTML</figcaption></figure><p>En el fragmento de código CSS anterior, utilizo <code>flexbox</code> para centrar todo en la página.</p><p>El elemento <code>div</code> contenedor con la clase de <code>showcase</code> se posiciona de forma <code>relative</code>, por lo que puedes posicionar el texto <code>h1</code> de forma <code>absolute</code> dentro de él. Esto empujará el texto <code>h1</code> a la esquina superior izquierda de la imagen. Las propiedades <code>top</code> y <code>left</code> se utilizan entonces para empujar el texto a la esquina inferior izquierda de la imagen.</p><p>Si se pregunta qué son las propiedades <code>top</code> e <code>left</code>, son las propiedades a las que se accede cuando se utiliza la propiedad display.</p><p>Además de estas dos, también tienes acceso a las propiedades <code>right</code> e <code>bottom</code>. Estas te permiten posicionar un elemento en cualquier lugar.</p><p>Al final, la imagen es opaca y el texto no se ve afectado:<br></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/09/right-opacity.png" class="kg-image" alt="right-opacity" width="600" height="400" loading="lazy"><figcaption>Imagen con opacidad</figcaption></figure><h2 id="conclusi-n">Conclusión</h2><p>En este artículo, has aprendido a utilizar la propiedad de opacity de CSS para hacer que las imágenes sean transparentes.</p><p>Como el CSS sigue siendo complicado y un poco raro, es útil combinar la propiedad de opacity con otras características de CSS, como el posicionamiento, para poder utilizarla correctamente.</p><p>Aparte del posicionamiento CSS, también se puede utilizar la propiedad de <code>opacity</code> con elementos pseudo CSS como <code>::before</code> y <code>::after</code>, que es otra forma de hacerlo.</p><p>Gracias por leer y sigue codificando.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Cadena de Java a Int: Cómo convertir una cadena en un número entero ]]>
                </title>
                <description>
                    <![CDATA[ Artículo original escrito por Thanoshan MV [https://www.freecodecamp.org/news/author/thanoshan/] Artículo original Java String to Int – How to Convert a String to an Integer [https://www.freecodecamp.org/news/java-string-to-int-how-to-convert-a-string-to-an-integer/] Traducido y adaptado por Santiago Yanguas [https://twitter.com/ToqYang] Los objetos de cadena son representados como una cadena de caracteres. Si has trabajado en Java Swing, tiene componentes como ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/cadena-de-java-a-int-como-convertir-una-cadena-en-un-numero-entero/</link>
                <guid isPermaLink="false">61fefb8de56f6e08aa1c5290</guid>
                
                    <category>
                        <![CDATA[ java ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Santiago Toquica Yanguas ]]>
                </dc:creator>
                <pubDate>Thu, 10 Feb 2022 19:59:59 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2022/02/java-string.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><strong>Artículo original escrito por </strong><a href="https://www.freecodecamp.org/news/author/thanoshan/">Thanoshan MV </a><br><strong>Artículo original </strong><a href="https://www.freecodecamp.org/news/java-string-to-int-how-to-convert-a-string-to-an-integer/">Java String to Int – How to Convert a String to an Integer</a><br><strong>Traducido y adaptado por </strong><a href="https://twitter.com/ToqYang">Santiago Yanguas</a></p><p>Los objetos de cadena son representados como una cadena de caracteres.</p><p>Si has trabajado en Java Swing, tiene componentes como JTextField y JTextArea que utilizamos para obtener nuestra entrada de la GUI. Toma nuestra entrada como una cadena de caracteres.</p><p>Si queremos hacer una calculadora simple usando Swing, tenemos que averiguar cómo convertir una cadena en un número entero. Esto nos lleva a la pregunta: ¿cómo podemos convertir una cadena en un número entero?</p><p>En Java, podemos utilizar <code>Integer.valueOf()</code> e <code>Integer.parseInt()</code> para convertir una cadena en un entero.</p><h2 id="1-utiliza-integer-parseint-para-convertir-una-cadena-en-un-n-mero-entero">1. Utiliza Integer.parseInt() para convertir una cadena en un número entero</h2><p>Este método devuelve la cadena como un <strong>tipo primitivo int</strong>. Si la cadena no contiene un entero válido, lanzará una <a href="https://docs.oracle.com/javase/7/docs/api/java/lang/NumberFormatException.html">NumberFormatException</a>.</p><p>Por lo tanto, cada vez que convirtamos una cadena en un int, tenemos que ocuparnos de esta excepción colocando el código dentro del bloque try-catch.</p><p>Consideremos un ejemplo de conversión de una cadena a un int utilizando <code>Integer.parseInt()</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-Java">        String str = "25";
        try {
            int number = Integer.parseInt(str);
            System.out.println(number); // output = 25
        }
        catch (NumberFormatException ex){
            ex.printStackTrace();
        }</code></pre><figcaption>Convertir cadena de texto a entero</figcaption></figure><p>Intentemos romper este código introduciendo un entero no válido:</p><figure class="kg-card kg-code-card"><pre><code class="language-Java">     	String str = "25T";
        try{
            int number = Integer.parseInt(str);
            System.out.println(number);
        }
        catch (NumberFormatException ex){
            ex.printStackTrace();
        }</code></pre><figcaption>Prueba de la excepción</figcaption></figure><p>Como puedes ver en el código anterior, hemos intentado convertir <code>25T</code> en un número entero. Esto no es una entrada válida. Por lo tanto, debes lanzar una NumberFormatException.</p><p>Este es el resultado del código anterior:</p><figure class="kg-card kg-code-card"><pre><code class="language-java">java.lang.NumberFormatException: For input string: "25T"
	at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.lang.Integer.parseInt(Integer.java:580)
	at java.lang.Integer.parseInt(Integer.java:615)
	at OOP.StringTest.main(StringTest.java:51)</code></pre><figcaption>Mensaje de la excepción</figcaption></figure><p>A continuación, veremos cómo convertir una cadena de caracteres en un número entero utilizando el método <code>Integer.valueOf()</code>.</p><h2 id="2-utiliza-integer-valueof-para-convertir-una-cadena-en-un-n-mero-entero">2. Utiliza Integer.valueOf() para convertir una cadena en un número entero</h2><p>Este método devuelve la cadena como un <strong>objeto entero</strong>. Si miras la <a href="https://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#valueOf(java.lang.String)">documentación de Java</a>, <code>Integer.valueOf()</code> devuelve un objeto entero que equivale a un nuevo <code>Integer(Integer.parseInt(s))</code>.</p><p>Colocaremos nuestro código dentro del bloque try-catch cuando utilicemos este método. Consideremos un ejemplo utilizando el método <code>Integer.valueOf()</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-java">        String str = "25";
        try{
            Integer number = Integer.valueOf(str);
            System.out.println(number); // output = 25
        }
        catch (NumberFormatException ex){
            ex.printStackTrace();
        }</code></pre><figcaption>Convertir cadena a un número entero</figcaption></figure><p>Ahora, intentemos romper el código anterior introduciendo un número entero no válido:</p><figure class="kg-card kg-code-card"><pre><code class="language-java">        String str = "25TA";
        try{
            Integer number = Integer.valueOf(str);
            System.out.println(number); 
        }
        catch (NumberFormatException ex){
            ex.printStackTrace();
        }</code></pre><figcaption>Probar la excepción</figcaption></figure><p>Al igual que en el ejemplo anterior, el código anterior lanzará una excepción.</p><p>Este es el resultado del código anterior:</p><figure class="kg-card kg-code-card"><pre><code class="language-Java">java.lang.NumberFormatException: For input string: "25TA"
	at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.lang.Integer.parseInt(Integer.java:580)
	at java.lang.Integer.valueOf(Integer.java:766)
	at OOP.StringTest.main(StringTest.java:42)</code></pre><figcaption>Excepción</figcaption></figure><p>También podemos crear un método para comprobar si la cadena pasada es numérica o no antes de utilizar los métodos mencionados.</p><p>He creado un método sencillo para comprobar si la cadena pasada es numérica o no.</p><figure class="kg-card kg-code-card"><pre><code class="language-java">public class StringTest {
    public static void main(String[] args) {
        String str = "25";
        String str1 = "25.06";
        System.out.println(isNumeric(str));
        System.out.println(isNumeric(str1));
    }

    private static boolean isNumeric(String str){
        return str != null &amp;&amp; str.matches("[0-9.]+");
    }
}</code></pre><figcaption>Comprobar si es una cadena es solo de numeros</figcaption></figure><p>La salida es:</p><figure class="kg-card kg-code-card"><pre><code class="language-Java">true
true</code></pre><figcaption>Salida</figcaption></figure><p>El método <code>isNumeric()</code> toma una cadena como argumento. Primero comprueba si es <code>null</code> o no. Después utilizamos el método <code>matches()</code> para comprobar si contiene dígitos del 0 al 9 y un carácter de punto.</p><p>Esta es una forma sencilla de comprobar los valores numéricos. Puedes escribir o buscar en Google expresiones regulares más avanzadas para capturar valores numéricos dependiendo de tu caso de uso.</p><p>Es una buena práctica comprobar si la cadena pasada es numérica o no antes de intentar convertirla a entero.</p><p>Gracias por leer.</p><p>Imagen por <a href="https://unsplash.com/@itfeelslikefilm?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">?? Janko Ferlič</a> en <a href="https://unsplash.com/collections/139346/soul-care?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></p><p>Puedes conectarte conmigo en <a href="https://mvthanoshan.medium.com/">Medium</a>.</p><p><strong>¡Feliz codificación!</strong></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Tutorial de Array.filter() de JavaScript: Como iterar a través los elementos en un arreglo ]]>
                </title>
                <description>
                    <![CDATA[ Artículo original escrito por Kingsley Ubah [https://www.freecodecamp.org/news/author/ubahthebuilder/] Artículo original JavaScript Array.filter() Tutorial – How to Iterate Through Elements in an Array [https://www.freecodecamp.org/news/javascript-array-filter-tutorial-how-to-iterate-through-elements-in-an-array/] Traducido y adaptado por Santiago Yanguas [https://twitter.com/ToqYang] El método Array.filter() es posiblemente el método más importante y ampliamente utilizado para iterar sobre un  ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/tutorial-de-arrayfilter-de-javascript-como-iterar-a-traves-de-los-elementos-en-un-arreglo/</link>
                <guid isPermaLink="false">616f52085658740999353235</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Santiago Toquica Yanguas ]]>
                </dc:creator>
                <pubDate>Thu, 28 Oct 2021 12:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2021/10/filter-cover.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><strong>Artículo original escrito por </strong><a href="https://www.freecodecamp.org/news/author/ubahthebuilder/">Kingsley Ubah</a><br><strong>Artículo original </strong><a href="https://www.freecodecamp.org/news/javascript-array-filter-tutorial-how-to-iterate-through-elements-in-an-array/">JavaScript Array.filter() Tutorial – How to Iterate Through Elements in an Array</a><br><strong>Traducido y adaptado por </strong><a href="https://twitter.com/ToqYang">Santiago Yanguas</a></p><p>El método <code>Array.filter()</code> es posiblemente el método más importante y ampliamente utilizado para iterar sobre un arreglo en JavaScript.</p><p>El funcionamiento del método <code>filter()</code> es muy sencillo. Consiste en filtrar uno o más elementos (un subconjunto) de una colección más grande de elementos (un superconjunto) basándose en alguna condición/preferencia.<br>Todos hacemos esto todos los días, ya sea leyendo, eligiendo a nuestros amigos o a nuestro cónyuge, eligiendo qué película ver, etc.</p><h2 id="el-m-todo-array-filter-en-javascript">El método <code>Array.filter()</code> en JavaScript</h2><p>El método <code>filter()</code> toma una función callback y llama a esa función para cada elemento sobre el que itera dentro del arreglo de destino. La función callback de llamada puede tomar los siguientes parámetros:</p><ul><li><code>valorActual</code>: Es el elemento del arreglo sobre el que se está iterando actualmente.</li><li><code>indice</code>: Es la posición del índice del <code>valorActual</code> dentro del arreglo.</li><li><code>arreglo</code>: Representa el arreglo de destino(final) junto con todos sus elementos.</li></ul><p>El método <code>filter</code> crea un nuevo arreglo y devuelve todos los elementos que pasan la condición especificada en la llamada en el callback.</p><h2 id="c-mo-usar-el-m-todo-filter-en-javascript">Cómo usar el método <code>filter()</code> en JavaScript</h2><p>En los siguientes ejemplos, demostraré cómo se puede utilizar el método <code>filter()</code> para filtrar elementos de un arreglo en JavaScript.</p><h3 id="filter-ejemplo-1-c-mo-filtrar-elementos-de-un-arreglo"><code>filter()</code> Ejemplo 1: Cómo filtrar elementos de un arreglo</h3><p>En este ejemplo, filtramos todas las personas que son niños pequeños (cuya edad está comprendida entre 0 y 4 años).</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let gente = [
    {nombre: "aaron", edad: 65},
    {nombre: "beth", edad: 2},
    {nombre: "cara", edad: 13},
    {nombre: "daniel", edad: 3},
    {nombre: "ella", edad: 25},
    {nombre: "fin", edad: 1},
    {nombre: "george", edad: 43},
]

let pequeños = gente.filter(persona =&gt; persona.edad &lt;= 3)

console.log(pequeños);



/*
[{
  edad: 2,
  nombre: "beth"
}, {
  edad: 3,
  nombre: "daniel"
}, {
  edad: 1,
  nombre: "fin"
}]
*/</code></pre><figcaption>Personas &lt; de 4 años</figcaption></figure><h3 id="filter-ejemplo-2-c-mo-filtrar-elementos-en-funci-n-de-una-propiedad-concreta"><code>filter()</code> Ejemplo 2: Cómo filtrar elementos en función de una propiedad concreta</h3><p>En este ejemplo, solo filtraremos los miembros del equipo que sean desarrolladores.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let equipo = [
	{
  		nombre: "aaron",
    	posicion: "developer"
 	 },
  	{
  		nombre: "beth",
    	posicion: "ui designer"
  	},
  	{
  		nombre: "cara",
    	posicion: "developer"
  	},
 	{
  		nombre: "daniel",
    	posicion: "content manager"
 	 },
  	{
  		nombre: "ella",
    	posicion: "cto"
  	},
  	{
  		nombre: "fin",
    	posicion: "backend engineer"
  	},
  	{
  		nombre: "george",
    	posicion: "developer"
  },

]

let desarrolladores = equipo.filter(miembro =&gt; miembro.posicion == "developer")

console.log(desarrolladores);


/*
[{
  nombre: "aaron",
  posicion: "developer"
}, {
  nombre: "cara",
  posicion: "developer"
}, {
  nombre: "george",
  posicion: "developer"
}]
*/</code></pre><figcaption>Personas que sean (desarrolladores)developers</figcaption></figure><p>En el ejemplo anterior, hemos filtrado a los desarrolladores. Pero, ¿y si queremos filtrar a todos los miembros que <strong>no</strong> son desarrolladores?</p><p>Podríamos hacerlo:</p><pre><code class="language-js">let equipo = [
	{
  		nombre: "aaron",
    	posicion: "developer"
 	 },
  	{
  		nombre: "beth",
    	posicion: "ui designer"
  	},
  	{
  		nombre: "cara",
    	posicion: "developer"
  	},
 	{
  		nombre: "daniel",
    	posicion: "content manager"
 	 },
  	{
  		nombre: "ella",
    	posicion: "cto"
  	},
  	{
  		nombre: "fin",
    	posicion: "backend engineer"
  	},
  	{
  		nombre: "george",
    	posicion: "developer"
  },

]

let noDesarrolladores = equipo.filter(miembro =&gt; miembro.posicion !== "developer")

console.log(noDesarrolladores);


/*
[
    {
  		name: "beth",
  		position: "ui designer"
	}, 
    {
  		name: "daniel",
  		position: "content manager"
	}, 
    {
  		name: "ella",
  		position: "cto"
	}, 
    {
  		name: "fin",
  		position: "backend engineer"
	}
]

*/</code></pre><h3 id="filter-ejemplo-3-c-mo-acceder-a-la-propiedad-ndice"><code>filter()</code> Ejemplo 3: Cómo acceder a la propiedad índice</h3><p>Se trata de un concurso. En esta competición, hay tres ganadores. El primero obtendrá la medalla de oro, el segundo la de plata y el tercero, la de bronce.</p><p>Utilizando el <code>filter</code> y accediendo a la propiedad del <code>indice</code> de cada elemento en cada iteración, podemos filtrar cada uno de los tres ganadores en diferentes variables.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let ganadores = ["Anna", "Beth", "Cara"];

let oro = ganadores.filter((ganador, indice) =&gt; indice == 0);
let plata = ganadores.filter((ganador, indice) =&gt; indice == 1);
let bronce = ganadores.filter((ganador, indice) =&gt; indice == 2);

console.log(`Oro ganador: ${oro}, ganador de plata: ${plata}, ganador de bronze: ${bronce}`);

// "Oro ganador: Anna, Plata ganadora: Beth, Bronce ganador: Cara"</code></pre><figcaption>Premios basados en el indice</figcaption></figure><h3 id="filter-ejemplo-4-c-mo-utilizar-el-par-metro-arreglo"><code>filter()</code> Ejemplo 4: Cómo utilizar el parámetro arreglo</h3><p>Uno de los usos más comunes del tercer parámetro (arreglo) es inspeccionar el estado del arreglo sobre el que se está iterando. Por ejemplo, podemos comprobar si queda otro elemento en el arreglo. Dependiendo del resultado, podemos especificar que sucedan diferentes cosas.</p><p>En este ejemplo, vamos a definir un arreglo de cuatro personas. Sin embargo, como solo puede haber tres ganadores, la cuarta persona de la lista tendrá que ser descontada.</p><p>Para poder hacer esto, necesitamos obtener información sobre el arreglo de destino en cada iteración.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let competidores = ["Anna", "Beth", "Cara", "David"];

function mostrarGanadores(nombre, indice, arreglo) {
    let esSiguienteItem = indice + 1 &lt; arreglo.length ? true : false;
    if (esSiguienteItem) {
    	console.log(`El ganador #${indice+1} es ${name}.`);
    } else {
    	console.log(`Perdón, ${name} no es uno de los ganadores.`);
    }
}

competidores.filter((nombre, indice, arreglo) =&gt; mostrarGanadores(nombre, indice, arreglo))

/*
"El ganador #1 es Anna."
"El ganador #2 es Beth."
"El ganador #3 es Cara."
"Perdón, David no es uno de los ganadores."
*/</code></pre><figcaption>Encontrar los ganadores y el último sera perdedor</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/08/sorry.png" class="kg-image" alt="sorry" width="600" height="400" loading="lazy"><figcaption>Resultado con el anterior código en inglés</figcaption></figure><h3 id="c-mo-usar-el-objeto-de-contexto">Cómo usar el objeto de contexto</h3><p>Además de la función de devolución de llamada, el método <code>filter()</code> también puede recibir un objeto de contexto.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">filter(callbackfn, objetoContexto)</code></pre><figcaption>Objeto de contexto en filter</figcaption></figure><p>Este objeto puede ser referido desde dentro de la función del callback usando la referencia de la palabra clave <code>this</code>.</p><h3 id="filter-ejemplo-5-c-mo-acceder-al-objeto-contexto-con-this"><code>filter()</code> Ejemplo 5: Cómo acceder al objeto contexto con <code>this</code></h3><p>Esto va a ser similar al <code>ejemplo 1</code>. Vamos a filtrar a todas las personas que tengan entre 13 y 19 años (adolescentes).</p><p>Sin embargo, no codificaremos los valores dentro de la función callback. En su lugar, definiremos estos valores 13 y 19 como propiedades dentro del objeto <code>range</code>, que posteriormente pasaremos a <code>filter</code> como el objeto contexto (segundo parámetro).</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let personas = [
    {nombre: "aaron", edad: 65},
    {nombre: "beth", edad: 15},
    {nombre: "cara", edad: 13},
    {nombre: "daniel", edad: 3},
    {nombre: "ella", edad: 25},
    {nombre: "fin", edad: 16},
    {nombre: "george", edad: 18},
];

let rango = {
  bajo: 13,
  alto: 16
};


let jovenes = personas.filter(function(persona) {
	return persona.edad &gt;= this.bajo &amp;&amp; persona.edad &lt;= this.alto;
}, range)

console.log(jovenes)

/*
[{
  edad: 15,
  nombre: "beth"
}, {
  edad: 13,
  nombre: "cara"
}, {
  edad: 16,
  nombre: "fin"
}]
*/</code></pre><figcaption>Uso del objeto contexto</figcaption></figure><p>Pasamos el objeto <code>rango</code> como segundo argumento a <code>filter()</code>. En ese momento, se convirtió en nuestro objeto de contexto. En consecuencia, pudimos acceder a nuestros rangos superior e inferior en nuestra función de devolución de llamada con la referencia <code>this.alto</code> y <code>this.bajo</code> respectivamente.</p><h2 id="conclusiones">Conclusiones</h2><p>El método <code>filter()</code> del arreglo, filtra los elementos que coinciden con la expresión del callback y los devuelve.</p><p>Además de la función del callback, el método <code>filter</code> también puede tomar un objeto de contexto como segundo argumento. Esto te permitirá acceder a cualquiera de sus propiedades desde la función callback usando <code>this</code>.</p><p>Espero que hayas sacado algo útil de este artículo.</p><p><strong>Si quieres aprender más sobre el desarrollo web, no dudes en visitar mi <a href="https://ubahthebuilder.tech/my-top-10-youtube-channels-for-programmers">Blog</a>.</strong></p><p>Gracias por leer y hasta pronto.</p><blockquote><strong>P/S:</strong> Si, estás aprendiendo JavaScript, he creado un eBook que enseña 50 temas de JavaScript con notas digitales dibujadas a mano. <a href="https://ubahthebuilder.gumroad.com/l/js-50">Compruébalo aquí.</a></blockquote> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Tutorial de Array.map() de JavaScript: Como iterar a través de elementos en un arreglo con map() ]]>
                </title>
                <description>
                    <![CDATA[ Artículo original escrito por Kingsley Ubah [https://www.freecodecamp.org/news/author/ubahthebuilder/] Artículo original JavaScript Array.map() Tutorial – How to Iterate Through Elements in an Array with map() [https://www.freecodecamp.org/news/array-map-tutorial/] Traducido y adaptado por Santiago Yanguas [https://twitter.com/ToqYang] Cuando salió ES6 (EmcaScript 2015), introdujo un nuevo conjunto de métodos para iterar sobre un arreglo. Uno de los ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/tutorial-de-arraymap-de-javascript-como-iterar-a-atraves-de-elementos-en-un-arreglo-con-map/</link>
                <guid isPermaLink="false">616f3afd5658740999353038</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Santiago Toquica Yanguas ]]>
                </dc:creator>
                <pubDate>Wed, 27 Oct 2021 12:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2021/10/array-map.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><strong>Artículo original escrito por </strong><a href="https://www.freecodecamp.org/news/author/ubahthebuilder/">Kingsley Ubah</a><br><strong>Artículo original </strong><a href="https://www.freecodecamp.org/news/array-map-tutorial/">JavaScript Array.map() Tutorial – How to Iterate Through Elements in an Array with map()</a><br><strong>Traducido y adaptado por </strong><a href="https://twitter.com/ToqYang">Santiago Yanguas</a></p><p>Cuando salió ES6 (EmcaScript 2015), introdujo un nuevo conjunto de métodos para iterar sobre un arreglo. Uno de los más útiles es el método <code>map()</code>.</p><p><code>Array.prototype.map()</code> es un método incorporado en los arreglos, para iterar a través de los elementos dentro de una colección de arreglos en JavaScript. Piensa en él, como un bucle para avanzar de un elemento a otro en una lista, manteniendo el orden y la posición de cada elemento.</p><p>Este método <a href="https://www.freecodecamp.org/espanol/news/que-es-una-funcion-callback-javascript/">toma una función callback</a>, que se llama por cada nuevo elemento sobre el que se itera.</p><p>La función callback recibe tres parámetros:</p><ul><li>El valor actual.</li><li>Su índice.</li><li>El arreglo de destino</li></ul><p>Si eres un novato que lucha por entender cómo usar el método <code>map()</code> o qué hace exactamente, entonces este artículo es para ti.</p><h2 id="c-mo-funciona-el-m-todo-map-en-javascript">Cómo funciona el método <code>map()</code> en JavaScript</h2><p>Imagínate esto: hay una cola de personas en la puerta de un hospital esperando a ser vacunadas. Esto significa que aún no han sido vacunados.</p><p>Uno por uno, un médico administra la vacuna a todos ellos. El médico lo hace repitiendo la fila. En un extremo, hay un grupo de personas que aún no han sido vacunadas. El médico toma a todos y cada uno de ellos, les administra la vacuna y los devuelve a una <strong>nueva</strong> línea de personas vacunadas.</p><p>En un extremo, hay un arreglo (A) sobre el que se quiere operar. <code>map()</code> toma todos los elementos de ese arreglo (A), realiza una acción coherente sobre cada uno de esos elementos y los devuelve en un nuevo arreglo (B).</p><h2 id="c-mo-utilizar-el-m-todo-map-ejemplo-de-vengadores">Cómo utilizar el método <code>map()</code>: Ejemplo de vengadores</h2><p>Para ilustrar cómo funciona <code>map()</code> en JavaScript, consideremos una lista de nombres de algunos de nuestros Vengadores favoritos. El problema es que los nombres de esta lista no están completos: les falta un sufijo importante.</p><p>Con <code>map()</code>, podemos tomar todos los nombres de la matriz y añadir el sufijo "man" a todos y cada uno de ellos:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let prefijos = ["super", "spider", "ant", "iron"]
let sufijo = "man";

let nombresCompletos = prefijos.map(prefijo =&gt; prefijo + sufijo);

console.log(nombresCompletos);

// ["superman", "spiderman", "antman", "ironman"]</code></pre><figcaption>Añadiendo el sufijo man a cada superheroe</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/08/map1-1.png" class="kg-image" alt="map1-1" width="600" height="400" loading="lazy"><figcaption>VISUAL CODE</figcaption></figure><h3 id="-qu-pasa-con-las-mujeres-women-">¿Qué pasa con las mujeres(women)?</h3><p>Lo siento, mi error. Me di cuenta de mi error y decidí incluir un personaje femenino en la <strong>primera</strong> posición del arreglo. Cada elemento dentro de un arreglo se identifica por un valor único, su índice (o posición en el arreglo). El primer elemento tendrá un <strong>índice</strong> de <code>0</code>, el segundo un índice de <code>1</code>, y así sucesivamente.</p><p>Dado que ahora hay una superheroína en la lista, tendremos que asegurarnos de añadir el sufijo correcto a la superheroína correspondiente.</p><p>Dado que <code>map()</code> también toma el índice del elemento sobre el que estamos iterando, podemos hacer esto comprobando el índice de nuestro héroe y asegurándonos de que utilizamos el sufijo "woman" para el primer elemento de nuestra matriz:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let prefijos = ["wonder", "spider", "ant", "iron"]
let hombre = "man";
let mujer = "woman";

let nombresCompletos = prefijos.map(function(prefijo, indice) {
    return (indice == 0) ? prefijo + mujer : prefijo + hombre;
 });

console.log(nombresCompletos);

["wonderwoman", "spiderman", "antman", "ironman"]</code></pre><figcaption>Nombre completos</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/08/map--8.png" class="kg-image" alt="map--8" width="600" height="400" loading="lazy"><figcaption>Resultado</figcaption></figure><h3 id="c-mo-utilizar-el-argumento-del-ndice">Cómo utilizar el argumento del índice</h3><p>Además del valor sobre el que se itera, <code>map</code> toma también su posición de índice. Esto es muy útil si quieres realizar diferentes tipos de operaciones dependiendo de la posición del índice del elemento.</p><p>En el ejemplo anterior, añadimos un sufijo diferente comprobando el índice.</p><p>Para conocer la posición del índice de cada uno de nuestros elementos dentro del arreglo, podemos hacer lo siguiente:</p><pre><code class="language-js">let nombresCompletos = ["wonderwoman", "spiderman", "antman", "ironman"]

nombresCompletos.map(function(nombre, indice) {
    console.log(${nombre} esta en la posición ${indice});
});

/* Resultado del anterior código
"wonderwoman esta en la posición 0"
"spiderman esta en la posición 0"
"antman esta en la posición 0"
"ironman esta en la posición 0"
*/</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/08/map--1.png" class="kg-image" alt="map--1" width="600" height="400" loading="lazy"><figcaption>Resultado del código original en inglés</figcaption></figure><h3 id="multiplicar-todos-los-elementos-del-arreglo-por-2">Multiplicar todos los elementos del arreglo por 2</h3><p>Trabajemos ahora un poco con los números. En este ejemplo, simplemente queremos multiplicar cada número del arreglo de destino por dos y luego devolver sus productos en un nuevo arreglo:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let numeros = [10, 20, 30, 40]
let multiplicador = 2;

let productos = numeros.map(numero =&gt; numero * multiplicador);

console.log(productos);

// [20, 40, 60, 80]</code></pre><figcaption>arreglo de numeros multiplicados por 2</figcaption></figure><h3 id="redondear-al-n-mero-entero-m-s-cercano">Redondear al número entero más cercano</h3><p>¿Qué pasa si tenemos un arreglo de decimales, pero queremos que cada uno de esos números decimales se redondee al entero más cercano?</p><figure class="kg-card kg-code-card"><pre><code>let numeros = [3.7, 4.9, 6.2]
let redondeados = numeros.map(function(numero) {
    return Math.round(numero);
})

console.log(redondeados);

// [4, 5, 6]</code></pre><figcaption>Arreglo de números redondeados</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/08/map--2.png" class="kg-image" alt="map--2" width="600" height="400" loading="lazy"><figcaption>Resultado</figcaption></figure><h3 id="cambiar-cadenas-de-texto-por-n-meros">Cambiar cadenas de texto por números</h3><p>Tenemos una lista de números que son de tipo <code>string</code> (cadena). Sin embargo, queremos convertir cada uno de ellos al tipo <code>Number</code> (número):</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let textos = ["10","20","30"]

let numeros = textos.map(function(texto) {
    return Number(texto);
})

console.log(numeros);

// [10, 20, 30]</code></pre><figcaption>Cadenas de texto a numeros</figcaption></figure><h3 id="conseguir-nombres-reales-de-los-vengadores">Conseguir nombres reales de los Vengadores</h3><p>En este ejemplo, estamos trabajando con objetos. Tenemos cinco vengadores en el arreglo y cada uno tiene tanto un nombre real como un nombre de héroe. Sin embargo, solo queremos recuperar sus nombres reales en el nuevo arreglo.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let vengadores = [
    {nombre: "steve rogers", nombreHeroe: "captain america"},
    {nombre: "tony stark", nombreHeroe: "iron man"},
    {nombre: "bruce banner", nombreHeroe: "the hulk"},
    {nombre: "peter parker", nombreHeroe: "spiderman"},
    {nombre: "tchalla", nombreHeroe: "black panther"}
]

let nombresReales = vengadores.map(vengador =&gt; vengador.nombre);

console.log(nombresReales);

// ["steve rogers", "tony stark", "bruce banner", "peter parker", "tchalla"]</code></pre><figcaption>Arreglo de nombres</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/08/map--5-1.png" class="kg-image" alt="map--5-1" width="600" height="400" loading="lazy"><figcaption>Resultado del nombre de los vengadores</figcaption></figure><h3 id="conseguir-los-nombres-de-los-h-roes-de-los-vengadores">Conseguir los nombres de los héroes de los Vengadores</h3><p>Para obtener solo sus nombres de héroe, hacemos casi lo mismo, solo que en este caso accedemos a la propiedad <code>nombreHeroe</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let vengadores = [
    {nombre: "steve rogers", nombreHeroe: "captain america"},
    {nombre: "tony stark", nombreHeroe: "iron man"},
    {nombre: "bruce banner", nombreHeroe: "the hulk"},
    {nombre: "peter parker", nombreHeroe: "spiderman"},
    {nombre: "tchalla", nombreHeroe: "black panther"}
];

let nombresReales = vengadores.map(vengador =&gt; vengador.nombreHeroe);

console.log(nombresReales);

// ["captain america", "iron man", "the hulk", "spiderman", "black panther"]</code></pre><figcaption>Resultado del nombre de los vengadores</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/08/map--10.png" class="kg-image" alt="map--10" width="600" height="400" loading="lazy"><figcaption>Resultado</figcaption></figure><h3 id="c-mo-separar-una-funci-n-para-a-adir-a-map">Cómo separar una función para añadir a <code>map</code></h3><p>En lugar de definir una función directamente dentro de <code>map()</code>, podemos definir la función fuera y luego llamarla dentro de nuestra función <code>map()</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">let vengadores = [
    {nombre: "steve rogers", nombreHeroe: "captain america"},
    {nombre: "tony stark", nombreHeroe: "iron man"},
    {nombre: "bruce banner", nombreHeroe: "the hulk"},
    {nombre: "peter parker", nombreHeroe: "spiderman"},
    {nombre: "tchalla", nombreHeroe: "black panther"}
];

let obtenerNombre = vengador =&gt; vengador.nombre;
let nombresReales = vengadores.map(obtenerNombre);

console.log(nombresReales);

// ["steve rogers", "tony stark", "bruce banner", "peter parker", "tchalla"]</code></pre><figcaption>Quitar complejidad al map mediante separación de funciones</figcaption></figure><h3 id="c-mo-funciona-el-argumento-del-arreglo">Cómo funciona el argumento del arreglo</h3><p>Antes dije que en cada iteración, el método <code>map()</code> toma el valor sobre el que se itera y también su posición de <code>indice</code>. Hay otro argumento que añadir a esos dos, los argumentos del <code>arreglo</code>.</p><p>El argumento <code>arr</code> representa el arreglo de destino sobre el que se hace un bucle, junto con todo su contenido. Con este argumento, se puede buscar en el arreglo completo para encontrar algo.</p><p>En este ejemplo, accederemos al parámetro <code>arr</code> para buscar y comprobar si el elemento actual es el último de la lista. Si no lo es, accedemos al siguiente elemento y lo restamos del elemento actual. Si es el último, simplemente lo devolvemos.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">const arregloViejo = [33, 20, 10, 5];
const nuevoArreglo = arregloViejo.map((valorActual, indice, arr) =&gt; {
    let siguienteItem = indice + 1 &lt; arr.length ? arr[indice + 1] : 0
    return valorActual - siguienteItem;
});


console.log(nuevoArreglo);

// [13, 10, 5, 5]</code></pre><figcaption>Buscar en el arreglo total</figcaption></figure><h2 id="conclusiones">Conclusiones</h2><p>El método <code>map()</code> fue introducido en ES6. Con este método, podemos acceder y realizar una acción consistente en cada elemento dentro de una colección de arreglos.</p><p>Toma una función callback que llama por cada nuevo elemento sobre el que itera.</p><p>En este tutorial, he introducido el método <code>map()</code>, he ilustrado su funcionamiento con una analogía y he dado algunos ejemplos prácticos de su uso en código JavaScript.</p><p>Espero que hayas sacado algo útil de este artículo. Si te gustan los tutoriales relacionados con la programación como este, <a href="https://ubahthebuilder.tech">deberías visitar mi blog</a>. Allí publico regularmente artículos sobre desarrollo de software.</p><p>Gracias por leer y hasta pronto.<br><strong>P/S:</strong> Si estás aprendiendo JavaScript, he creado un eBook que enseña 50 temas en JavaScript con notas digitales dibujadas a mano. <a href="https://ubahthebuilder.gumroad.com/l/js-50">Compruébalo aquí</a>.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Desarrollo web para principiantes: Aprende HTML básico y CSS para construir tu página web ]]>
                </title>
                <description>
                    <![CDATA[ Artículo original escrito por Vasyl Lagutin [https://www.freecodecamp.org/news/author/coderslang/] Artículo original Web Development for Beginners – Learn Basic HTML and CSS to Build Your First Web Page [https://www.freecodecamp.org/news/web-development-for-beginners-basic-html-and-css/] Traducido y adaptado por Santiago Yanguas [https://twitter.com/ToqYang] ¿Te has preguntado alguna vez cómo se construyen y diseñan los sitios web? ¿Desea aprender el arte ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/desarrollo-web-para-principiantes-aprende-html-basico-y-css-para-construir-tu-pagina-web/</link>
                <guid isPermaLink="false">6154f2e5c757580942e5bfb4</guid>
                
                    <category>
                        <![CDATA[ Desarrollo Web ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Santiago Toquica Yanguas ]]>
                </dc:creator>
                <pubDate>Fri, 08 Oct 2021 12:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2021/10/halgatewood-com-tZc3vjPCk-Q-unsplash--1-.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><strong>Artículo original escrito por </strong><a href="https://www.freecodecamp.org/news/author/coderslang/">Vasyl Lagutin</a><br><strong>Artículo original </strong><a href="https://www.freecodecamp.org/news/web-development-for-beginners-basic-html-and-css/">Web Development for Beginners – Learn Basic HTML and CSS to Build Your First Web Page</a><br><strong>Traducido y adaptado por </strong><a href="https://twitter.com/ToqYang">Santiago Yanguas</a></p><p>¿Te has preguntado alguna vez cómo se construyen y diseñan los sitios web? ¿Desea aprender el arte del desarrollo web, pero no es tan experto en tecnología, todavía?</p><p>Bueno, entonces este tutorial es para ti. Es una introducción al desarrollo web para principiantes, para que puedas aprender lo básico incluso si eres totalmente nuevo en el tema.</p><h1 id="conceptos-b-sicos-de-html-la-estructura-de-una-p-gina-web">Conceptos básicos de HTML: la estructura de una página web</h1><p>HTML significa <code>Hyper-Text Markup Language</code>. Antes de adentrarnos en el funcionamiento de HTML, vamos a tener una comprensión básica de lo que significa realmente <code>Hyper-Text Markup Language</code>.</p><p>El <code>Hyper-Text</code> se refiere a los hipervínculos que se ven en un texto, una imagen o un marcador que redirige a otra página, archivo, documento u otra parte de una página web. </p><p>Un lenguaje de marcado es simplemente un lenguaje informático que contiene etiquetas que definen elementos dentro de un documento. Un ejemplo de etiqueta podría ser el titular de un blog, que normalmente se escribe como una etiqueta <code>h</code>.</p><p>Hay más etiquetas, algunas de las cuales descubriremos más adelante.</p><p>Puedes pensar simplemente en HTML como la estructura de una página web. Supongamos que tienes que construir una casa. El primer paso de la construcción debe ser construir su estructura general, ¿verdad?</p><p>Diseñará el sótano, las paredes, el césped, el garaje, etc. Así es como puedes imaginar el HTML: son los bloques de construcción de una página web.</p><p>En un sitio web, puede contener la barra de navegación, el cuerpo principal/contenido, el pie de página, la barra lateral y todas las divisiones estructurales de la página. Todo ello con HTML.</p><h2 id="c-mo-empezar-con-html">Cómo empezar con HTML</h2><p>Hay muchos editores de código, como VS Code, Sublime Text 3, Atom y Brackets. Todos estos pueden sonar extraños para ti. Así que empezamos usando <code>Notepad</code> que podemos usar de una forma u otra para escribir notas u otras cosas.</p><p>Veamos cómo se haría la estructura de una página web sencilla en HTML con código básico.</p><p>Vamos a diseñar una página web que tiene diferentes secciones: una barra de navegación, el cuerpo principal con un título, un párrafo, una imagen, y un pie de página.</p><figure class="kg-card kg-code-card"><pre><code class="language-html">&lt;!DOCTYPE html&gt;

&lt;html&gt;
    &lt;head&gt;
        &lt;title&gt;Título de la página&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;

        &lt;nav&gt;Esta es el Navbar de mi página web&lt;/nav&gt;

        &lt;h1&gt;Mi primera título&lt;/h1&gt;
        &lt;p&gt;Mi primer párrafo.&lt;/p&gt;

        &lt;img src = "https://miro.medium.com/max/1584/1*lJ32Bl-lHWmNMUSiSq17gQ.png"/&gt;

        &lt;footer&gt;
          &lt;p&gt;Pie de página&lt;/p&gt;
        &lt;/footer&gt;

    &lt;/body&gt;
&lt;/html&gt;</code></pre><figcaption>Página basica</figcaption></figure><p>En el código anterior, la declaración <code>&lt;!DOCTYPE html&gt;</code> significa que este documento es un archivo HTML5.</p><p>El <code>5</code> de arriba solo se refiere a la versión, ya que HTML ha avanzado mucho y ha mejorado respecto a sus versiones anteriores. La versión <code>5</code> solo se refiere a su última versión estable. No tienes que preocuparte por las versiones anteriores.</p><p><code>&lt;html&gt;</code> actúa como elemento raíz de todos los elementos (título, encabezados, párrafos, etc.) de una página web HTML.</p><p><code>&lt;head&gt;</code> contiene la metainformación (información sobre datos como el autor, la fecha de caducidad, una lista de palabras clave, el autor del documento) de la página.</p><p>El <code>&lt;title&gt;</code> refiere al título de la página web, que se ve en el navegador cuando se abre una página web. Aquí hay un ejemplo para tu referencia. En esta imagen, <code>Page Title</code> se refiere a la etiqueta title.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/05/Screenshot_-1313-.png" class="kg-image" alt="Understanding%20Web%20design%20Basics%20with%20HTML%20&amp;%20CSS%20f00187c06fae4c0582422f7947326b9b/Screenshot_(1313).png" width="600" height="400" loading="lazy"><figcaption>Título de la página</figcaption></figure><p><code>&lt;body&gt;</code> es donde está todo el contenido de tu página web, como el encabezado, los párrafos, las imágenes, toda la interfaz de usuario.</p><p><code>&lt;nav&gt;</code> representa la barra de navegación, que debe estar en la parte superior, seguida del cuerpo de contenidos principal y por último, el <code>&lt;footer&gt;</code>.</p><p>El cuerpo principal está compuesto por un encabezado representado por una etiqueta <code>&lt;h1&gt;</code> (el <code>1</code> con la <code>h</code> representa el tamaño del encabezado. El tamaño del encabezado va de 1 a 6, siendo 1 el más grande y 6 el más pequeño). Le sigue una etiqueta <code>&lt;p&gt;</code> de párrafo, luego una etiqueta de imagen <code>&lt;img&gt;</code>, finalmente el pie de página, la última sección de una página web.</p><p>Observe que la etiqueta de la imagen tiene la palabra clave <code>src</code> que se refiere a la fuente de la imagen, que en este caso es una imagen tomada de la web. Por eso adjuntamos el enlace URL de la imagen.</p><p>Todas estas etiquetas comienzan con un mayor y menor que <code>&lt;&gt;</code>; también finalizan con un mayor y menor que <code>&lt;/&gt;</code> con una barra inclinada de por medio, como puedes ver en los fragmentos de código.</p><h2 id="c-mo-guardar-los-archivos-html-y-mostrar-los-resultados">Cómo guardar los archivos HTML y mostrar los resultados</h2><p>Solo tienes que seguir estos dos pasos básicos para ver tu HTML como página web.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/05/Screenshot_-1319-.png" class="kg-image" alt="Understanding%20Web%20design%20Basics%20with%20HTML%20&amp;%20CSS%20f00187c06fae4c0582422f7947326b9b/Screenshot_(1319).png" width="600" height="400" loading="lazy"><figcaption>Página web</figcaption></figure><ol><li>Guarde su archivo HTML con la extensión <code>.html</code>. En el ejemplo que hemos utilizado, hemos guardado el archivo como <code>Tutorial.html</code>.</li></ol><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/05/Screenshot_-1322-.png" class="kg-image" alt="Understanding%20Web%20design%20Basics%20with%20HTML%20&amp;%20CSS%20f00187c06fae4c0582422f7947326b9b/Screenshot_(1322).png" width="600" height="400" loading="lazy"><figcaption>Página web</figcaption></figure><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/05/Screenshot_-1321-.png" class="kg-image" alt="Understanding%20Web%20design%20Basics%20with%20HTML%20&amp;%20CSS%20f00187c06fae4c0582422f7947326b9b/Screenshot_(1321).png" width="600" height="400" loading="lazy"><figcaption>Página web basica</figcaption></figure><p>2. Abra el archivo en cualquier navegador (Chrome, Firefox, IE), y entonces podrá ver su página web HTML.</p><h2 id="resultados-de-nuestro-dise-o-html-b-sico">Resultados de nuestro diseño HTML básico</h2><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/05/_C__Users_wel_Desktop_Tutorial.html_-2-.png" class="kg-image" alt="Understanding%20Web%20design%20Basics%20with%20HTML%20&amp;%20CSS%20f00187c06fae4c0582422f7947326b9b/_C__Users_wel_Desktop_Tutorial.html_(2).png" width="600" height="400" loading="lazy"><figcaption>HTML básico</figcaption></figure><p>Puedes ver claramente los resultados, aunque todavía no hay colores ni estilo. Aunque todavía se mira que la estructura está ahí - la barra de navegación, seguida por el cuerpo principal que contiene el contenido, luego por un pie de página en la parte inferior.</p><h1 id="c-mo-a-adir-colores-estilo-y-potencia-al-html-con-css">Cómo añadir colores, estilo y potencia al HTML con CSS</h1><p>CSS son las siglas de <code>Cascading Style Sheets</code> (hojas de estilo en cascada), que son los archivos de hojas de diseño que añaden colores, estilo y potencia a los elementos estructurales de tu HTML.</p><p>Puede pensar en el CSS como la pintura, la decoración y los elementos de diseño que añade para que tu casa quede bonita.</p><p>Existen múltiples formas de añadir CSS a tu estructura HTML. Vamos a explorar la técnica más básica que es añadir CSS a través de la etiqueta <code>&lt;style&gt;</code>.</p><figure class="kg-card kg-code-card"><pre><code class="language-html">&lt;head&gt;
	&lt;title&gt;Título página&lt;/title&gt;
    
    &lt;style&gt;

    body {
      background-color: lightblue;
      margin: 0;
      text-align: center;
    }

    nav {
     background-color: black;
     width: 100%;
     color: white;
     height: 50px;
     padding-top: 25px;
    }

    h1 {
     color: black;
    }

    footer {
     background-color: gray;
     color: white;
     padding: 5px;
    }

    &lt;/style&gt;
&lt;/head&gt;</code></pre><figcaption>CSS creado con la etiqueta style en el head</figcaption></figure><h2 id="explicaci-n-del-anterior-css">Explicación del anterior CSS</h2><p>Puedes ver que hemos añadido el CSS a través de la etiqueta style dentro de la etiqueta head del documento en el código anterior. Esta es una forma básica de añadir CSS.</p><p>Vamos a desglosar y explorar las propiedades CSS que hemos utilizado en los cuatro elementos anteriores.</p><h3 id="el-elemento-body">El elemento body</h3><figure class="kg-card kg-code-card"><pre><code class="language-css">body {
  background-color: lightblue;
  margin: 0;
  text-align: center;
}</code></pre><figcaption>Estilo aplicado a body</figcaption></figure><p>El selector CSS del cuerpo se refiere a toda la estructura de la interfaz de usuario que vemos. Añade algunas propiedades de CSS:</p><ul><li><code>background-color</code> añade el color de fondo - aquí es azul claro.</li><li><code>margin</code> que gestiona los espacios a ambos lados de la estructura de la página web.</li><li><code>text-aligned: center</code> significa que todo el contenido estará alineado al centro en este caso.</li></ul><p>Todo este CSS aplica a la página web, todos los elementos se enlazarán automáticamente estas propiedades generales CSS hasta que se especifiquen sus propias propiedades que difieran de estas globales.</p><h3 id="el-elemento-nav">El elemento nav</h3><figure class="kg-card kg-code-card"><pre><code class="language-css">nav {
 background-color: black;
 width: 100%;
 color: white;
 height: 50px;
 padding-top: 25px;
}</code></pre><figcaption>Elemento nav de la página web</figcaption></figure><p>El selector nav se refiere a la barra de navegación de la página web, la cual aplica propiedades de diseño.</p><p>Hemos establecido el color de fondo en negro, su anchura en <code>100%</code> para que ocupe todo el ancho, su <code>color</code> que representa el color del texto o enlaces dentro de la barra de navegación, su <code>height</code>(altura) en <code>50px</code> y le hemos dado un <code>padding-top</code> de <code>25px</code>.</p><p>El <code>padding</code> se refiere al espacio entre el contenido y el borde. Como queremos que el texto esté <code>alineado al centro</code>, tenemos que añadir un padding de la mitad de los píxeles de la altura real de la barra de navegación, es decir, <code>50px (altura de la barra de navegación) / 2 = 25px</code>. Esto asegurará que el texto dentro de la barra de navegación esté alineado al centro.</p><h3 id="elemento-h1">Elemento h1</h3><figure class="kg-card kg-code-card"><pre><code class="language-css">h1 {
 color: black;
}</code></pre><figcaption>Título h1</figcaption></figure><p>El selector <code>h1</code> aplica CSS a la etiqueta <code>h1</code> en el HTML. Por consiguiente la propiedad de <code>color</code> sea <code>black</code>(negro).</p><h3 id="elemento-footer">Elemento footer</h3><figure class="kg-card kg-code-card"><pre><code class="language-css">footer {
 background-color: gray;
 color: white;
 padding: 5px;
}</code></pre><figcaption>Pie de página en CSS</figcaption></figure><p>Este es el último selector que se refiere al pie de página de nuestra web. Aquí, hemos establecido un conjunto similar de propiedades que discutimos anteriormente para la <code>navbar</code>(barra de navegación), así que no hay nada realmente nuevo aquí.</p><p>¡Y eso es todo!</p><h1 id="qu-aspecto-tiene-la-p-gina-web-despu-s-de-a-adir-el-css">Qué aspecto tiene la página web después de añadir el CSS</h1><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/05/_C__Users_wel_Desktop_Tutorial.html_-1-.png" class="kg-image" alt="Understanding%20Web%20design%20Basics%20with%20HTML%20&amp;%20CSS%20f00187c06fae4c0582422f7947326b9b/_C__Users_wel_Desktop_Tutorial.html_(1).png" width="600" height="400" loading="lazy"><figcaption>Página web con CSS</figcaption></figure><p>Ahora puedes ver cuánta vida puede añadirle el CSS a nuestra estructura básica de HTML. ¿No es increíble?</p><p>Estos son solo los fundamentos del diseño web, pero en realidad es bastante divertido una vez que los aprendes.</p><h1 id="conclusi-n-">Conclusión:</h1><p>Ahora que aprendiste los fundamentos del diseño de páginas web, puede ver lo accesible que puede ser, lo práctico que es y cómo se relaciona con muchos conceptos de la vida real, como la construcción de una casa.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Explicando async y await en JavaScript cocinando pizzas ]]>
                </title>
                <description>
                    <![CDATA[ Artículo original escrito por Dave Gray [https://www.freecodecamp.org/news/author/dave/] Artículo original Async and Await in JavaScript Explained by Making Pizza [https://www.freecodecamp.org/news/async-await-javascript-tutorial-explained-by-making-pizza/] Traducido y adaptado por Santiago Yanguas [https://twitter.com/ToqYang] Async y await pueden parecer complicados... pero son tan fáciles como una tarta de pizza una vez que te sumerges en ellos. Todos utilizamos ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/explicando-async-y-await-en-javascript-con/</link>
                <guid isPermaLink="false">613c09e4fbc6fd08e9058a8a</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Santiago Toquica Yanguas ]]>
                </dc:creator>
                <pubDate>Mon, 20 Sep 2021 12:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2021/09/pizza.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><strong>Artículo original escrito por </strong><a href="https://www.freecodecamp.org/news/author/dave/">Dave Gray</a><br><strong>Artículo original </strong><a href="https://www.freecodecamp.org/news/async-await-javascript-tutorial-explained-by-making-pizza/">Async and Await in JavaScript Explained by Making Pizza</a><br><strong>Traducido y adaptado por </strong><a href="https://twitter.com/ToqYang">Santiago Yanguas</a></p><p>Async y await pueden parecer complicados... pero son tan fáciles como una tarta de pizza una vez que te sumerges en ellos.</p><p>Todos utilizamos async y await en nuestras rutinas diarias.</p><h2 id="-qu-es-una-tarea-as-ncrona">¿Qué es una tarea asíncrona?</h2><p>Una tarea asíncrona le permite completar otras tareas mientras la tarea asíncrona sigue trabajando para completarse.</p><h3 id="estos-son-algunos-ejemplos-de-tareas-as-ncronas-del-d-a-a-d-a">Estos son algunos ejemplos de tareas asíncronas del día a día</h3><h4 id="ejemplo-1-">Ejemplo 1:</h4><p>Pides comida en un autoservicio, el cual inicia a procesar su solicitud de comida (una tarea asíncrona).</p><p>Avanzas en la fila de conductores (la siguiente tarea), mientras se va preparando su comida.</p><p>No había que esperar que la comida estuviera lista para poder avanzar.</p><p>Mientras conduces esperas tu comida, la cual se entrega en la ventanilla final.</p><h4 id="ejemplo-2-">Ejemplo 2:</h4><p>Trapeas el suelo de la cocina.</p><p>Mientras esperas que se seque el suelo de la cocina, aspiras la alfombra de tu dormitorio.</p><p>La tarea original era limpiar el suelo de la cocina y la tarea está completa cuando el suelo está seco.</p><p>Estar de pie esperando a que se seque el suelo no es demasiado productivo, así que aspiras el suelo del dormitorio mientras se seca el de la cocina.</p><p><em>Así es como JavaScript maneja también las funciones asíncronas.</em></p><h3 id="ejemplo-de-async-await-hornear-una-pizza-congelada">Ejemplo de Async/Await - Hornear una pizza congelada</h3><p>Decides hornear una pizza en tu horno y tu primer paso es precalentar el horno.</p><p>Así que sé fijas la temperatura deseada y empiezas a precalentar el horno.</p><p>Mientras se precalienta el horno, sacas la pizza del congelador, abres la caja y la pones en una sartén para pizza.</p><p>¡Te queda tiempo!</p><p>Tal vez, puedes tomar una bebida y ver algo de televisión mientras esperas que el horno emita un ¡beep!, cuando esté listo.</p><p>A continuación se muestra un código para simular este ejemplo:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">// Esta función asíncrona simula la respuesta del horno
const hornoListo = async () =&gt; {
  return new Promise(resolve =&gt; setTimeout(() =&gt; {
    resolve('Beep! Horno Calentado!')
  }, 3000));
}

// Definir la función asíncrona preCalentarHorno
const preCalentarHorno = async () =&gt; {
  console.log('Pre calentar horno.');
  const respuesta = await hornoListo();
  console.log(respuesta);
}

// Definir las otras funciones
const obtenerPizzaFria = () =&gt; console.log('Obtener pizza.');
const abrirPizzaFria = () =&gt; console.log('Abrir pizza.');
const obtenerSartenPizza = () =&gt; console.log('Obtener sarten.');
const ponerPizzaSarten = () =&gt; console.log('Poner pizza en el sarten.');
const tomarRefresco = () =&gt; console.log('Tomar un refresco.');
const mirarTV = () =&gt; console.log('Ver la televisión.');

// Ahora llama a las funciones
preCalentarHorno();
obtenerPizzaFria();
abrirPizzaFria();
obtenerSartenPizza();
ponerPizzaSarten();
tomarRefresco();
mirarTV();

// Secuencia de salida en la consola:
Pre calentar horno.
Obtener pizza.
Abrir pizza.
Obtener sarten.
Poner pizza en el sarten.
Tomar un refresco.
Ver la televisión.
Beep! Horno Calentado!</code></pre><figcaption>Calentar pizza, mientras tomo un refresco y ver televisión</figcaption></figure><p>El proceso anterior es exactamente lo que significa async y await.</p><p>Mientras <code>await</code>(esperamos) a que se complete la función asíncrona <code>preCalentarHorno</code>, podemos realizar tareas síncronas como <code>obtenerPizzaFria</code>, <code>abrirPizzaFria</code>, <code>obtenerSartenPizza</code>, <code>ponerPizzaSarten</code>, <code>tomarRefresco</code> e incluso <code>mirarTV</code>.</p><h3 id="realizamos-tareas-as-ncronas-casi-todo-el-tiempo">Realizamos tareas asíncronas casi todo el tiempo</h3><p>Así es como funciona también el JavaScript <code>asíncrono</code>.</p><p>Fíjate que cuando <code>await</code>(esperamos) la respuesta de una función <code>async</code>(asíncrona) esta debe ser llamada dentro de otra función <code>async</code>(asíncrona). Eso es lo que vemos arriba cuando <code>hornoListo</code> es llamado dentro de <code>preCalentarHorno</code>.</p><h3 id="hay-que-recordar-dos-puntos-clave-">Hay que recordar dos puntos clave:</h3><ol><li>JavaScript NO esperará a que una función <code>async</code>(asíncrona) como <code>preCalentarHorno</code> se complete antes de pasar a las tareas que le siguen como <code>obtenerPizzaFria</code> y <code>abrirPizzaFria</code>.</li><li>JavaScript <code>await</code>(esperará) a que una función <code>async</code>(asíncrona) como <code>hornoListo</code> se complete, devuelva datos antes de pasar a la siguiente tarea dentro de una función asíncrona padre. Vemos esto cuando la sentencia <code>console.log(respuesta)</code> no se ejecuta hasta que <code>hornoListo</code> haya devuelto una respuesta.</li></ol><h2 id="si-el-ejemplo-de-la-pizza-no-es-suficiente-">Si el ejemplo de la pizza no es suficiente...</h2><p>Sé que los ejemplos cotidianos nos ayudan a algunos, aunque otros pueden preferir el código real.</p><p>Por lo tanto, voy a proporcionar un ejemplo menos abstracto de JavaScript async y await que solicita datos con la API Fetch:</p><h2 id="ejemplo-de-c-digo-async-await-en-javascript">Ejemplo de código Async/Await en JavaScript</h2><figure class="kg-card kg-code-card"><pre><code class="language-js">const obtenerDatos = async () =&gt; {
    try {
    const respuesta = await fetch('https://jsonplaceholder.typicode.com/users');
    if (!response.ok) throw Error();
    const datos = await response.json();
    // Hacer algo con estos datos... guardar en la db, actualizar el DOM, etc.
    console.log(datos);
    console.log('Verás esto último.')
    } catch (err) {
        console.error(err);
    }
} 

obtenerDatos();
console.log('Esto es lo primero que verás.');
</code></pre><figcaption>Obtener en JavaScript</figcaption></figure><h1 id="conclusi-n">Conclusión</h1><p>Espero haberte ayudado a entender async y await en JavaScript.</p><p>Sé que puede llevar un tiempo comprenderlo completamente.</p><p>Empieza a precalentar la pizza que se te antoja en tu horno y mira algunos ejemplos más de async y await mientras esperas él ¡beep!</p><p>Dejo un tutorial de mi canal de YouTube. El video da una explicación más profunda, con más ejemplos de código, incluyendo una discusión de callbacks, promesas, resoluciones y la API Fetch junto con async &amp; await:</p><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.25%;" class="fluid-width-video-wrapper">
            <iframe src="https://www.youtube.com/embed/VmQ6dHvnKIM?feature=oembed" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" name="fitvid0" frameborder="0" width="256" height="144"></iframe>
          </div>
        </div>
      </figure><hr> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ ¿Qué es un archivo JSON? Ejemplo de código en JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ Artículo original escrito por Kolade Chris [https://www.freecodecamp.org/news/author/kolade/] Artículo original What is a JSON File? Example JavaScript Code [https://www.freecodecamp.org/news/what-is-a-json-file-example-javascript-code/] Traducido y adaptado por Santiago Yanguas [https://twitter.com/ToqYang] JSON son las siglas de "JavaScript Object Notation". Un archivo JSON, tiene como extensión los .json, además los datos que contiene son representados en un ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/que-es-un-archivo-json-ejemplo-de-codigo-en-javascript/</link>
                <guid isPermaLink="false">6137fd1a1162fd09748f405c</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Santiago Toquica Yanguas ]]>
                </dc:creator>
                <pubDate>Fri, 17 Sep 2021 12:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2021/09/json.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><strong>Artículo original escrito por </strong><a href="https://www.freecodecamp.org/news/author/kolade/">Kolade Chris</a><br><strong>Artículo original </strong><a href="https://www.freecodecamp.org/news/what-is-a-json-file-example-javascript-code/">What is a JSON File? Example JavaScript Code</a><br><strong>Traducido y adaptado por </strong><a href="https://twitter.com/ToqYang">Santiago Yanguas</a></p><p><strong>JSON</strong> son las siglas de "JavaScript Object Notation". Un archivo JSON, tiene como extensión los <code>.json</code>, además los datos que contiene son representados en un par <code>llave:valor</code>, igualmente que un objeto JavaScript tradicional.</p><p>Sin embargo, JSON y los objetos de JavaScript no son exactamente lo mismo. La diferencia principal es que la llave en JSON son los valores, aparte de los tipos número y nulo deben ir entre comillas dobles.</p><p>Si has trabajado con APIs durante tu trayectoria en programación, es probable que sepas lo que es JSON, porque muchos de los datos de las APIs vienen traen formato JSON.</p><p>Si, no has trabajado antes con APIs y eres principiante, no estás solo.</p><p>En este artículo, voy a explicarte en qué consiste el formato JSON y cómo puedes sacarle el máximo partido.</p><h2 id="sintaxis-b-sica-de-json">Sintaxis básica de JSON</h2><pre><code class="language-js">{
  "llave1": "valor1",
  "llave2": "valor2",
  "llave3": "valor3",
  "llave4": 7,
  "llave5": null,
  "favAmigos": ["Kolade", "Nithya", "Dammy", "Jack"],
  "favJugadores": {"uno": "Kante", "dos": "Hazard", "tres": "Didier"}
}
</code></pre><h2 id="tipos-de-datos-json-aceptados">Tipos de datos JSON aceptados</h2><p>JSON podemos definirlo como un objeto o un arreglo que puede contener varios objetos. Por lo tanto, objetos y arreglos son tipos de datos automáticamente aceptables en JSON. Otros tipos de datos que se admite son booleanos, nulos y cadenas de texto.</p><p>Los tipos de datos <a href="https://www.freecodecamp.org/espanol/news/p/b293db5e-c8e8-44f8-9c0f-d681623291fd/luisignacioccp@gmail.com"><code>undefined</code>,</a> <code>function</code> y <code>date</code> no son compatibles con JSON.</p><p>Además, JSON también puede extenderse a otros tipos de datos adicionales que JSON puro no acepta.</p><p>Ejemplos de estas extensiones son GeoJSON y BSON. GeoJSON se utiliza para representar datos geográficos, mientras que BSON es utilizado por el popular proveedor de servicios de bases de datos MongoDB.</p><p>BSON, por ejemplo, acepta expresiones regulares, fechas y marcas de tiempo como tipos de datos, que JSON no acepta.</p><h2 id="reglas-para-sintaxis-json">Reglas para sintaxis JSON</h2><p>JSON es muy estricto en cuanto a los tipos de datos soportados. Si tienes un linter instalado en tu editor de código, te avisará inmediatamente de que hay un error cada vez que introduces un tipo de datos no soportado o vas en contra de las reglas de sintaxis.</p><h3 id="reglas-de-sintaxis-json-que-hay-que-conocer-">Reglas de sintaxis JSON que hay que conocer:</h3><ul><li>Todos los datos del archivo deben estar rodeados de llaves <strong><code>{}</code></strong> si quieres representar un objeto y entre corchetes cuadrados si es un arreglo <strong><code>[]</code></strong>.</li><li>Las comillas simples no están permitidas.</li><li>La llave en cada JSON debe ser única y debe estar entre comillas dobles.</li><li>Los números no deben ir entre comillas dobles, de lo contrario se tratarán como cadenas de texto.</li><li>El tipo de dato null no debe ir entre comillas dobles.</li><li>Los valores booleanos solo pueden ser verdaderos o falsos.</li><li>Cada par llave:valor debe terminar con una coma, excepto el último elemento</li><li>Un solo objeto dentro de un arreglo debe terminar también con una coma.</li></ul><h2 id="c-mo-se-env-an-los-datos-json-al-cliente-navegador-">Cómo se envían los datos JSON al cliente (navegador)</h2><p>JSON surgió de la necesidad de enviar datos desde el servidor (una base de datos, por ejemplo) al cliente (los navegadores) en tiempo real.</p><p>Pero los datos JSON no pueden ser transmitidos al navegador en su forma cruda en un par llave:valor. Debido a esto los lenguajes de programación tienen métodos para manipular los datos JSON.</p><p>En JavaScript, por ejemplo, <code>JSON.parse()</code> convierte los datos JSON en objetos y <code>JSON.stringify()</code> convierte el par llave:valor de un objeto en datos JSON.</p><p>Python proporciona métodos como: <code>json.loads()</code> para convertir una cadena existente en JSON y <code>json.dumps()</code> para convertir un objeto en una cadena de texto JSON.</p><p>Puedes enviar los datos en sintaxis JSON, al navegador utilizando los dos métodos que proporciona JavaScript.</p><h3 id="c-mo-enviar-datos-json-al-cliente-navegador-con-javascript">Cómo enviar datos JSON al cliente (navegador) con JavaScript</h3><p>El método <code>JSON.stringify()</code> devuelve una cadena de texto JSON, la cual traducida es exactamente igual a un objeto en JavaScript. Puedes utilizarlo en combinación con los métodos de manipulación del DOM para mostrar datos, como he hecho en los fragmentos de código siguientes:</p><figure class="kg-card kg-code-card"><pre><code class="language-html">&lt;h2&gt;Aquí están los datos del JSON::&lt;/h2&gt; 
&lt;div id="json"&gt;&lt;/div&gt;
</code></pre><figcaption>HTML sin rellenar</figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-js"> const JSONData = {
    "key1": "value1",
    "key2": "value2",
    "key3": "value3",
    "key4": 7,
    "key5": null,
    "favFriends": ["Kolade", "Nithya", "Dammy", "Jack"],
    "favPlayers": {"one": "Kante", "two": "Hazard", "three": "Didier"}
}

const JSONString = JSON.stringify(JSONData)
const JSONDisplay = document.querySelector("#json")
JSONDisplay.innerHTML = JSONString
</code></pre><figcaption>Código de ejemplo</figcaption></figure><p>En el código JavaScript, declaramos los datos JSON como un objeto literal con el identificador (nombre) <code>JSONData</code>. Utilizamos el método <code>JSON.stringify()</code> de JavaScript, para convertirlo en una cadena, y el método query selector del DOM para obtener el div vacío en el HTML. Esto permite rellenar los datos JSON en él, con el método de manipulación DOM <code>innerHTML</code>.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/08/json-stringify-method.png" class="kg-image" alt="json-stringify-method" width="600" height="400" loading="lazy"><figcaption>Resultado del código de ejemplo</figcaption></figure><p>Podemos utilizar el método <code>JSON.parse()</code> para convertir un dato JSON en un objeto y aquí está en acción:</p><figure class="kg-card kg-code-card"><pre><code class="language-html">&lt;h2&gt;Aquí están los datos del JSON:&lt;/h2&gt;
&lt;div id="json"&gt;&lt;/div&gt;
</code></pre><figcaption>Aqui estan los datos del JSON</figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-js">const JSONData =
     '{"name": "Kolade", "favFriends": ["Kolade", "Nithya", "Rocco", "Jack"], "from": "Africa"}';

   try {
     const JSONString = JSON.parse(JSONData);
     const JSONDisplay = document.querySelector("#json");
     JSONDisplay.innerHTML = JSONString.name + ", [" + JSONString.favFriends + "], " + JSONString.from;
   } catch (error) {
     console.log("No puedo parsear JSON Data");
   }
</code></pre><figcaption>JSON data</figcaption></figure><p>La salida resultante en el navegador tiene el siguiente aspecto:<br></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/08/json-parse-method.png" class="kg-image" alt="json-parse-method" width="600" height="400" loading="lazy"><figcaption>Resultado de fragmento del JSON</figcaption></figure><h2 id="conclusi-n-">Conclusión:</h2><p>Como programador, no puedes prescindir de JSON. La mayoría de las APIs están ahora escritas en JSON en lugar de XML.</p><p>JSON fue inicialmente concebido para JavaScript, pero muchos otros lenguajes de programación lo soportan ahora gracias a su naturaleza independiente del lenguaje. Como resultado, muchos lenguajes tienen bibliotecas para trabajar con él.</p><p>Espero que este tutorial te haya proporcionado los conocimientos necesarios para trabajar con JSON, Ojalá puedas darle un uso adecuado cada vez que lo encuentres.</p><p>Gracias por leer, sigue codificando.</p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
