Comenzando con Next.js

 

 

 

  • Implemente rápidamente. Implementar inteligentemente
  • Taller de diseño conductual, con Susan y Guthrie Weinschenk

  • Índice
    1. Pero ¿por qué Next.js?
    2. Requisitos para crear una aplicación Next.js
    3. Creando una aplicación Next.js
      1. Creando una aplicación Next.js concreate-next-app
      2. Crear un proyecto Next.js manualmente
    4. Estructura de carpetas
    5. paginas
    6. Enrutamiento
      1. Rutas de índice
      2. Rutas anidadas
      3. Segmentos de ruta dinámicos
    7. Vinculación entre páginas
    8. Estilo
    9. Linting y formato
    10. Activos estáticos
    11. Obtención de datos
    12. getStaticProps
    13. getStaticPaths
    14. Extras
      1. Importaciones absolutas
      2. Características experimentales de ES
    15. Conclusión
      1. Recursos

    Next.js es un marco de React que seguramente le facilitará la vida como desarrollador de React al abstraer las tareas comunes y redundantes (como el enrutamiento) en API relativamente más simples y potentes. De esa manera, podrás concentrarte en escribir tus aplicaciones en lugar de reinventar la rueda.

     

    Últimamente, Next.js se ha autodenominado The React Framework for Production , y con una afirmación tan audaz viene una serie de características que ofrece para ayudarlo a llevar sus sitios web React de cero a producción. Estas características importarían menos si Next.js no fuera relativamente fácil de aprender, y si bien las numerosas características pueden significar más cosas y matices que aprender, su intento de simplicidad, potencia y tal vez éxito es definitivamente algo que debe tener en su arsenal.

    A medida que se prepara para aprender sobre Next.js, hay algunas cosas con las que quizás ya esté familiarizado e incluso puede que se sorprenda de cómo le brinda tanto con qué trabajar que puede parecer casi abrumador a primera vista. Next.js está pensado para sitios estáticos y ha sido bien diseñado para ese propósito. Pero también va más allá con su regeneración estática incremental que combina bien con las funciones existentes para hacer del desarrollo una experiencia relajante. Pero espera, podrías preguntar. ¿Por qué Next.js?

    Este tutorial será beneficioso para los desarrolladores que quieran comenzar con Next.js o que ya hayan comenzado pero necesiten llenar algunos vacíos de conocimiento. No es necesario ser un profesional en React; sin embargo, tener experiencia laboral con React será útil.

    Pero ¿por qué Next.js?

    1. Relativamente fácil de aprender.
      Eso es todo. Si ha escrito algún React, se sentirá como en casa con Next.js. Le ofrece herramientas avanzadas y un sólido soporte API, pero no le obliga a utilizarlas.
    2. Soporte CSS incorporado.
      Escribir CSS en marcos basados ​​en componentes conlleva una necesidad sacrosanta de la "cascada". Es por eso que tiene herramientas CSS-in-JS , pero Next.js viene listo para usar con su propia oferta: styled-jsx y también admite una gran cantidad de metodologías de estilo.
    3. Soporte automático de TypeScript.
      Si le gusta codificar en TypeScript, con Next.js, literalmente tiene soporte automático para la configuración y compilación de TypeScript.
    4. Técnica de obtención de datos múltiples.
      Soporta SSG y/o SSR. Puedes optar por utilizar uno u otro, o ambos.
    5. Enrutamiento del sistema de archivos.
      Navegar entre una página y otra es posible a través del sistema de archivos de su aplicación. No necesita ninguna biblioteca especial para manejar el enrutamiento.

    Hay muchas más características, por ejemplo, usar características experimentales de ES como encadenamiento opcional , no importar reacciones en todos los lugares donde usa JSX, soporte para API como next/headesa que ayuda a administrar el encabezado de su documento HTML, etc. Basta decir que cuanto más profundiza, más disfruta, aprecia y descubre muchas otras funciones.

    Requisitos para crear una aplicación Next.js

    La creación de una aplicación Next.js requiere Node.js y npm(o npx) instalado.

    Para verificar si tiene Node.js instalado, ejecute el comando en su terminal:

    # It should respond with a version numbernode -v

    Idealmente, npm (y npx) vienen con su instalación de Node.js. Para confirmar que los tienes instalados, ejecuta los comandos en tu terminal:

    # Run this. It should respond with a version numbernpm -v# Then run this. It should also respond with a version numbernpx -v

    En caso de que alguno de los comandos anteriores no responda con un número de versión, es posible que desee considerar la posibilidad de instalar Node.js y npm .

    Si prefieres el administrador de paquetes de hilo , puedes ejecutar instalarlo con el comando:

    # Installs yarn globallynpm i -g yarn

    Luego confirme la instalación con:

    # It should also respond with a version numberyarn -v

    Creando una aplicación Next.js

    Eliminando los requisitos anteriores, la creación de Next.js se puede realizar de dos maneras, siendo la primera la más simple:

    1. Con create-next-app , o
    2. A mano

    Creando una aplicación Next.js concreate-next-app

    Usar create-next-app es simple y directo, además también puedes comenzar con un iniciador como Next.js con Redux , Next.js con Tailwind CSS o Next.js con Sanity CMS , etc. Puedes ver la lista completa de principiantes en el repositorio de ejemplos de Next.js.

    # Create a new Next.js app with npxnpx create-next-app app-name# Create a new Next.js app with npmnpm create-next-app app-name# With yarnyarn create next-app app-name

    Si se pregunta cuál es la diferencia entre npm y npx, hay un artículo detallado en el blog de npm, Introducing npx: an npm package runner .

    Crear un proyecto Next.js manualmente

    Esto requiere tres paquetes: next, reacty react-dom.

    # With npmnpm install next react react-dom# With yarnyarn add next react react-dom

    Luego agregue los siguientes scripts a package.json.

    "scripts": { "dev": "next dev", "start": "next start", "build": "next build"}
    • devinicia Next.js en modo de desarrollo .
    • startinicia Next.js en modo de producción .
    • buildconstruye su aplicación Next.js para producción .

    Estructura de carpetas

    Una cosa destacada que puede notar después de crear una aplicación Next.js es la estructura sencilla de carpetas. Obtienes lo mínimo para ejecutar una aplicación Next.js. Ni mas ni menos. Lo que obtengas a medida que tu aplicación crece depende más de ti que del marco.

     

    Las únicas carpetas específicas de Next.js son las carpetas pages, publicy styles.

    # other files and folders, .gitignore, package.json...- pages - api - hello.js - _app.js - index.js- public - favicon.ico - vercel.svg- styles - globals.css - Home.module.css

    paginas

    En una aplicación Next.js, las páginas son una de las carpetas específicas de Next que obtienes. Aquí hay algunas cosas que necesita saber pages:

    • Las páginas son componentes de React.
      Cada archivo que contiene es una página y cada página es un componente de React.
    // Location: /pages/homepage.js// HomePage/ is just a basic React componentexport default HomePage() { return h1Welcome to Next.js/h1}
    • Páginas personalizadas
      Estas son páginas especiales con el prefijo de guión bajo, como _app.js.

      • _app.js: Este es un componente personalizado que reside en la carpeta de páginas. Next.js usa este componente para inicializar páginas.
      • _document.js: Like _app.js, _document.jses un componente personalizado que Next.js utiliza para aumentar sus aplicaciones htmly bodyetiquetas. Esto es necesario porque las páginas Next.js omiten la definición del marcado del documento circundante.
    • Sistema de enrutamiento basado en archivos basado en páginas
      Next.js tiene un sistema de enrutamiento basado en archivos donde cada página se convierte automáticamente en una ruta según su nombre de archivo. Por ejemplo, una página en pages/profilese ubicará en /profiley pages/index.jsen /.

    # Other folders- pages - index.js # located at / - profile.js # located at /profile - dashboard - index.js # located at /dashboard - payments.js # located at /dashboard/payments

    Enrutamiento

    Next.js tiene un sistema de enrutamiento basado en archivos basado en pages. Cada página creada se convierte automáticamente en una ruta. Por ejemplo, pages/books.jsse convertirá en ruta /book.

    - pages - index.js # url: / - books.js # url: /books - profile.js # url: /profile

    El enrutamiento ha llevado a bibliotecas como React Router y puede ser desalentador y bastante complejo debido a la gran cantidad de formas que podría considerar adecuadas para enrutar la sección de sus páginas en su aplicación Next.js. Hablar de enrutamiento en Next.js es bastante sencillo; en su mayor parte, el sistema de enrutamiento basado en archivos se puede utilizar para definir los patrones de enrutamiento más comunes.

    Rutas de índice

    La pagescarpeta tiene automáticamente una página index.jsque se dirige automáticamente al punto de inicio de su aplicación como /. Pero puedes tener diferentes index.jscorreos electrónicos en tus páginas, pero uno en cada carpeta. No es necesario que haga esto, pero ayuda a definir el punto de partida de sus rutas y evitar cierta redundancia en la denominación. Tome esta estructura de carpetas, por ejemplo:

     

    - pages - index.js - users - index.js - [user].js

    Hay dos rutas de índice en /y /users. Es posible nombrar la ruta del índice en la userscarpeta users.jsy enrutarla /users/userssi es legible y conveniente para usted. De lo contrario, puede utilizar la ruta de índice para mitigar la redundancia.

    Rutas anidadas

    ¿Cómo estructura su carpeta para tener una ruta como /dashboard/user/:id.

    Necesitas carpetas anidadas:

    - pages - index.js - dashboard - index.js - user - [id].js # dynamic id for each user

    Puedes anidar y profundizar tanto como quieras.

    Segmentos de ruta dinámicos

    Los segmentos de una URL no siempre son indeterminados. A veces simplemente no se puede saber qué habrá en el desarrollo. Aquí es donde entran los segmentos de ruta dinámicos. En el último ejemplo, :idestá el segmento dinámico en la URL /dashboard/user/:id. Determina idel usuario que estará en la página actualmente. Si puedes pensar en ello, lo más probable es que puedas crearlo con el sistema de archivos.

    La parte dinámica puede aparecer en cualquier lugar de las rutas anidadas:

    - pages - dashboard - user - [id].js - profile

    proporcionará la ruta /dashboard/user/:id/profileque conduce a una página de perfil de un usuario con una identificación particular.

    Imagínese intentar acceder a una ruta /news/:category/:category-type/:league/:teamdonde category, category-type, leaguey teamson segmentos dinámicos. Cada segmento será un archivo y los archivos no se pueden anidar. Aquí es donde necesitarías rutas generales en las que distribuyas las partes dinámicas como:

    - pages - news - [...id].js

    Luego puedes acceder a la ruta como /news/sport/football/epl/liverpool.

    Quizás se pregunte cómo obtener segmentos dinámicos en sus componentes. El useRouteranzuelo, exportado desde next/routerestá reservado para ese fin y otros. Expone el routerobjeto.

    import { useRouter } from 'next/router';export default function Post() { // useRouter returns the router object const router = useRouter(); console.log({ router }); return div News /div;}

    Los segmentos dinámicos son querypropiedad del routerobjeto, al que se accede con router.query. Si no hay consultas, la propiedad de consulta devuelve un objeto vacío.

    Vinculación entre páginas

    Puede navegar entre páginas en sus aplicaciones con el componente Enlace exportado por next/link. Digamos que tienes las páginas:

    - pages - index.js - profile.js - settings.js - users - index.js - [user].js

    Puedes Linkdarles me gusta:

    import Link from "next/link";export default function Users({users) { return ( div Link href="/"Home/Link Link href="/profile"Profile/Link Link href="/settings" a Settings /a /Link Link href="/users" a Settings /a /Link Link href="/users/bob" a Settings /a /Link /div )}

    El componente Enlace tiene una serie de accesorios aceptables; href (la URL del hipervínculo) es el único requerido. Es equivalente al atributo del elemento ancla HTML ( ).href a Scifi books reviews

     

    Otros accesorios incluyen:

    Apuntalar Valor por defecto Descripción
    as Igual quehref Indica qué mostrar en la barra de URL del navegador.
    passHref FALSO Obliga al Linkcomponente a pasar el hrefaccesorio a su hijo./td
    prefetch verdadero Permite que Next.js busque de forma proactiva las páginas que se encuentran actualmente en la ventana gráfica incluso antes de que sean visitadas para lograr transiciones de página más rápidas.
    replace FALSO Reemplaza la navegación actual historyen lugar de insertar una nueva URL en la historypila.
    scroll verdadero Después de la navegación, la nueva página debe desplazarse hacia la parte superior.
    shallow FALSO Actualizar la ruta de la página actual sin volver a ejecutar getStaticProps, getServerSidePropso getInitialProps, permite que la página tenga datos obsoletos si está activado.

    Estilo

    Next.js viene con tres métodos de estilo listos para usar: CSS global, módulos CSS y styled-jsx.

    Hay un artículo extenso sobre el estilo en Next.js que se trató en Comparación de métodos de estilo en Next.js.

    Linting y formato

    Sospecho que el linting y el formateo son un tema muy obstinado, pero las métricas empíricas muestran que la mayoría de las personas que lo necesitan en su código base JavaScript parecen disfrutar de la compañía de ESLint y Prettier . Mientras que este último formatea idealmente, el primero altera su código base. Me he acostumbrado bastante a ESLint y Prettier Setup de Wes Bos porque extiende eslint-config-airbnb , interpola formatos más bonitos a través de ESLint, incluye valores predeterminados sensibles que en su mayoría funcionan (para mí) y pueden anularse si surge la necesidad.

    Incluirlo en su proyecto Next.js es bastante sencillo. Puede instalarlo globalmente si lo desea, pero lo haremos localmente .

    • Ejecute el siguiente comando en su terminal.
    # This will install all peer dependencies required for the package to worknpx install-peerdeps --dev eslint-config-wesbos
    • Cree un .eslintrcarchivo en la raíz de su aplicación Next.js, junto con la carpeta y pages, con el contenido:stylespublic
    { "extends": [ "wesbos" ]}

    En este punto, puede modificar y formatear su código manualmente o puede dejar que su editor tome el control.

     

    • Para lint y formatear manualmente es necesario agregar dos scripts npm lint y lint:fix.
    "scripts": { "dev": "next dev", "build": "next build", "start": "next start" "lint": "eslint .", # Lints and show you errors and warnings alone "lint:fix": "eslint . --fix" # Lints and fixes},
    • Si está utilizando VSCode y prefiere que su editor linte y formatee automáticamente, primero debe instalar el complemento ESLint VSCode y luego agregar los siguientes comandos a su configuración de VSCode:
    # Other setting"editor.formatOnSave": true,"[javascript]": { "editor.formatOnSave": false},"[javascriptreact]": { "editor.formatOnSave": false},"eslint.alwaysShowStatus": true,"editor.codeActionsOnSave": { "source.fixAll": true},"prettier.disableLanguages": ["javascript", "javascriptreact"],

    Nota : Puede obtener más información sobre cómo hacerlo funcionar con VSCode aquí .

    A medida que avanza, lo más probable es que necesite anular alguna configuración, por ejemplo, tuve que desactivar la regla reaccionar/jsx-props-no-spreading que genera errores cuando los accesorios JSX se distribuyen como en el caso de pagePropsSiguiente Componente de página personalizada .js, _app.js.

    function MyApp({ Component, pageProps }) { return Component {...pageProps} /;}

    Desactivar la regla es el siguiente:

    { "extends": [ "wesbos" ], "rules": { "react/jsx-props-no-spreading": 0 }}

    Activos estáticos

    En algunos o varios puntos de la vida útil de su aplicación Next.js, necesitará un activo u otro. Podrían ser íconos, fuentes autohospedadas o imágenes, etc. Para Next.js, esto también se conoce como servicio de archivos estáticos y existe una única fuente de verdad: la carpeta pública . Los documentos de Next.js advierten: No le ponga publicningún otro nombre al directorio. El nombre no se puede cambiar y es el único directorio utilizado para servir activos estáticos.

    Acceder a archivos estáticos es sencillo. Tome la estructura de carpetas siguiente, por ejemplo,

    - pages profile.js- public - favicon.ico #url /favicon.ico - assets - fonts - font-x.woff2 - font-x.woff # url: /assets/fonts/font-x.woff2 - images - profile-img.png # url: /assets/images/profile-img.png- styles - globals.css

    Puede acceder a la profile-img.pngimagen desde el Profile/componente:

    // Profile/ is a React componentexport default function Profile() { return { div className="profile-img__wrap" img src="/assets/images/profile-img.png" alt="a big goofy grin" / /div }}

    o las fuentes en la carpeta de fuentes en CSS:

    /* styles/globals.css */@font-face { font-family: 'font-x'; src: url(/assets/fonts/font-x.woff2) format('woff2'), url(/assets/fonts/font-x.woff) format('woff');}

    Obtención de datos

    La obtención de datos en Next.js es un tema enorme que requiere cierto nivel de esfuerzo. Aquí discutiremos el quid de la cuestión. Antes de profundizar, es necesario tener una idea de cómo Next.js representa sus páginas.

     

    El renderizado previo es una gran parte de cómo funciona Next.js, así como de lo que lo hace rápido. De forma predeterminada, Next.js prerenderiza cada página generando HTML de cada página por adelantado junto con el JavaScript mínimo que necesitan para ejecutar, a través de un proceso conocido como hidratación.

    Es posible, aunque poco práctico, desactivar JavaScript y seguir procesando algunas partes de su aplicación Next.js. Si alguna vez hace esto, considere hacerlo solo con fines mecánicos para mostrar que Next.js realmente hidrata las páginas renderizadas.

    Dicho esto, existen dos formas de renderizado previo:

    1. Generación estática (SG),
    2. Representación del lado del servidor (SSR).

    La diferencia entre los dos radica en cuándo se obtienen los datos. Para SG, los datos se obtienen en el momento de la compilación y se reutilizan en cada solicitud (lo que lo hace más rápido porque se pueden almacenar en caché), mientras que en SSR, los datos se obtienen en cada solicitud.

    Lo que ambos tienen en común es que se pueden combinar con renderizado del lado del cliente con fetch , Axios , SWR , React Query , etc.

    Las dos formas de renderizado previo no son un caso absoluto de uno u otro; puede optar por utilizar Generación estática o Representación del lado del servidor, o puede utilizar un híbrido de ambos. Es decir, mientras algunas partes de su aplicación Next.js usan Generación estática, otras pueden usar SSR.

    En ambos casos, Next.js ofrece funciones especiales para recuperar sus datos. Puede utilizar uno de los enfoques tradicionales para la obtención de datos en React o puede utilizar las funciones especiales. Es recomendable utilizar las funciones especiales, no porque supuestamente sean especiales, ni porque tengan un nombre apropiado (como verás), sino porque te brindan una técnica de obtención de datos centralizada y familiar con la que no puedes equivocarte. .

    Las tres funciones especiales son:

    1. getStaticProps— Se utiliza en SG cuando el contenido de su página depende de datos externos.
    2. getStaticPaths— Se utiliza en SG cuando las rutas de su página dependen de datos externos.
    3. getServerSideProps— utilizado en renderizado del lado del servidor.

    getStaticProps

    getStaticPropses hermano de getStaticPathsy se utiliza en Generación estática. Es una función asíncrona donde puede recuperar datos externos y devolverlos como accesorio al componente predeterminado de una página. Los datos se devuelven como un objeto de accesorios y se asignan implícitamente al accesorio del componente de exportación predeterminado en la página.

    En el siguiente ejemplo, necesitamos asignar las cuentas y mostrarlas; el contenido de nuestra página depende de los datos externos que obtuvimos y resolvimos en getStaticProps.

    // accounts get passed as a prop to AccountsPage/ from getStaticProps()// Much more like AccountsPage {...{accounts}} /export default function AccountsPage({accounts}) { return ( div h1Bank Accounts/h1 {accounts.map((account) = ( div key={account.id} p{account.Description}/p /div ))} /div )}export async function getStaticProps() { // This is a real endpoint const res = await fetch('https://sampleapis.com/fakebank/api/Accounts'); const accounts = await res.json(); return { props: { accounts: accounts.slice(0, 10), }, };}

    Como puede ver, getStaticPropsfunciona con Generación estática y devuelve un objeto de accesorios , de ahí el nombre.

     

    getStaticPaths

    Similar a getStaticProps, getStaticPathsse usa en Generación estática, pero se diferencia en que son las rutas de su página las que son dinámicas, no el contenido de su página. Esto se usa a menudo getStaticPropsporque no devuelve ningún dato a su componente en sí, sino que devuelve las rutas que deben renderizarse previamente en el momento de la compilación. Con el conocimiento de las rutas, puede continuar para buscar el contenido de la página correspondiente .

    Piense en Next.js renderizando previamente su página en el aspecto de una página dinámica con respecto a la generación estática. Para que pueda hacer esto correctamente en el momento de la compilación, debe saber cuáles son las rutas de las páginas. Pero no puede porque son dinámicos e indeterminados, ahí es donde getStaticPathsentra en juego.

    Imagina que tienes una aplicación Next.js con páginas Statesy stateque muestra una lista de países de Estados Unidos y un solo estado respectivamente. Es posible que tenga una estructura de carpetas similar a la siguiente:

    - pages - index.js - states - index.js # url: /states - [id].js # url /states/[id].js 

    Creas el [id].jspara mostrar un único estado basado en su id. Por lo tanto, el contenido de la página (datos devueltos por getStaticProps) dependerá de las rutas de la página (datos devueltos por getStaticPaths).

    Primero creemos los States/componentes.

    // The states will be passed as a prop from getStaticPropsexport default function States({states}) { // We'll render the states here}export async function getStaticProps() { // This is a real endpoint. const res = await fetch(`https://sampleapis.com/the-states/api/the-states`); const states = await res.json(); // We return states as a prop to States/ return { props: { states } };}

    Ahora creemos la página dinámica para un solo estado. Es la razón por la que tenemos eso [id].jspara que podamos hacer coincidir la ruta /states/1, o /states/2donde 1 y 2 están iden [id].js.

    // We start by expecting a state prop from getStaticPropsexport default function State({ state }) { // We'll render the states here}// getStaticProps has a params prop that will expose the name given to the// dynamic path, in this case, `id` that can be used to fetch each state by id.export async function getStaticProps({ params }) { const res = await fetch( `https://sampleapis.com/the-states/api/the-states?id=${params.id}` ); const state = await res.json(); return { props: { state: state[0] } };}

    Si intenta ejecutar el código tal como está, recibirá el mensaje: Error: getStaticPathses necesario para páginas SSG dinámicas y falta para /states/[id].

     

    // The state component// getStaticProps function// getStaticPathsexport async function getStaticPaths() { // Fetch the list of states const res = await fetch("https://sampleapis.com/the-states/api/the-states"); const states = await res.json(); // Create a path from their ids: `/states/1`, `/states/2` ... const paths = states.map((state) = `/states/${state.id}`); // Return paths, fallback is necessary, false means unrecognize paths will // render a 404 page return { paths, fallback: false };}

    Con el pathsretorno de getStaticPaths, getStaticPropsse le informará y sus paramsaccesorios se completarán con los valores necesarios, como iden este caso.

    Extras

    Importaciones absolutas

    Hay soporte para importación absoluta a partir de Next.js 9.4, lo que significa que ya no tienes que importar componentes como:

    import FormField from "../../../../../../components/general/forms/formfield"

    en su lugar, puedes hacerlo absolutamente como:

    import FormField from "components/general/forms/formfield";

    Para que esto funcione, necesitará un archivo jsconfig.jsono tsconfig.jsonpara JavaScript y TypeScript respectivamente, con el siguiente contenido:

    { "compilerOptions": { "baseUrl": "." }}

    Esto supone que la componentscarpeta existe en la raíz de su aplicación, junto con páginas, estilos y público.

    Características experimentales de ES

    Es posible utilizar algunas funciones experimentales como el operador coalescente nulo (??) y el encadenamiento opcional (?.) en su aplicación Next.js.

    export default function User({user) { return h1{person?.name?.first ?? 'No name'}/h1}

    Conclusión

    Según el equipo de Next.js, muchos de los objetivos que se propusieron lograr fueron los que se enumeran en Los 7 principios de las aplicaciones web enriquecidas y, a medida que avanza hacia el ecosistema y lo profundiza, se dará cuenta de que está en buenas manos como muchos otros usuarios que han elegido utilizar Next.js para impulsar sus sitios web/aplicaciones web. Pruébalo, si no lo has hecho, y si lo has hecho, sigue adelante.

    Recursos

    Comenzando con Next.js

    Comenzando con Next.js

    Implemente rápidamente. Implementar inteligentemente Taller de diseño conductual, con Susan y Guthrie Weinschenk Índice

    programar

    es

    https://pseint.es/static/images/programar-comenzando-con-next-1068-0.jpg

    2024-04-04

     

    Comenzando con Next.js
    Comenzando con Next.js

    Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

     

     

    Top 20