Next JS

Por 9.99€ al mes tendrás acceso completo a todos los cursos. Sin matrícula ni permanencia.

Nos permite crear páginas estáticas a partir de las páginas generadas dinámicamente por React.

Instalación y ejecución

npx create-next-app mynextapp

Para ejecutar el proyecto:

npm run dev

Generación de los HTML

NextJS utiliza por defecto un módulo llamado next/image para exportar las imágenes. Este módulo necesita ser configurado en el fichero next.config.js. Si queremos evitarnos esta configuración, podemos importar las imagenes directamente con import. Así lo haremos en esta guía.

Ejecutamos el siguiente comando para hacer una compilación tradicional como la que hacíamos en React:

npm run build

Finalmente, este comando genera los HTML a partir del build que hemos hecho:

next export

Ejecutar ambos comandos, consecutivamente, desde npm

Para poder ejecutar el siguiente comando directamente desde npm, añadiremos un script al package.json para facilitar la generación de los html:

"scripts": {
    ...
    "export": "next build && next export",
  },
npm run export

Links

Cada carpeta ubicada dentro de la carpeta /pages corresonderá a una url. Por ejemplo:

/pages/page2/index.js

Para cargar estas páginas sin refrescar la página actual, usaremos el módulo Link:

import Link from 'next/link';

export default () => (
  <div>
    <h1>Home</h1>
    <nav>
      <Link href="/page2">Help page</Link>
    </nav>
  </div>
);

Para cargar dinámicamente una url, sin pulsar sobre un botón de Link.

import { useRouter } from 'next/router';
...
const router = useRouter()
...
router.push('/dashboard');

Cargar una imagen

La dejaremos en una carpeta diferente de la carpeta pages (por ejemplo, en la carpeta public), la importaremos en nuestro componente y la usaremos usando .src:

<img src={e.src} />

Cargar una fuente

La ubicaremos en la raíz de la carpeta public y la cargaremos como siempre hacemos en CSS:

@font-face {
  font-family: 'rqr';
  src: url("/fuente.ttf");
}

Problema con la carga de fuentes en producción

Para que las tipografías carguen correctamente en producción, será necesario especificar la ruta absoluta de su ubicación.

styled.js
import getConfig from 'next/config'
const { publicRuntimeConfig } = getConfig();
const fontPrefix = publicRuntimeConfig.basePath ? publicRuntimeConfig.basePath + '/' : '';

export const GlobalStyle = createGlobalStyle`
    @font-face {
        font-family: font ;
        src: url(${fontPrefix}${font});
    }
`;
next.config.js
const isDevelopment = process.env.NODE_ENV === 'development';

const basePath = isDevelopment ? '' : '/ruta-en-produccion';

const plugins = config => withPlugins([withFonts, withImages], {
    ...config,
    publicRuntimeConfig: {
        basePath,
    },
    basePath,
});

Configurar el proyecto de NextJS para poder usar styled-components

Vamos a indicar a next.js que los ficheros terminados en page.js contienen páginas. De esta forma next.js no va a intentar compilar como página otros ficheros que no sea páginas, como por ejemplo, archivos de estilos.

module.exports = plugins({
    pageExtensions: ['page.js'],
    ...
});

Tras poner esta regla, tendremos que renombrar las páginas, _app.page.js, _document.page.js….

Next JS 1

Los ficheros que comienzan por barra baja ( _ ), son ficheros que nextJS reconoce y carga automáticamente. Esos ficheros con underscore dan problemas en github.com, para evitarlos, puedes leer esto.

./pages/_document.page.js
import Document from 'next/document';
import { ServerStyleSheet } from 'styled-components';

export const extractStyles = async (ctx) => {
  const sheet = new ServerStyleSheet();
  const originalRenderPage = ctx.renderPage;

  try {
    ctx.renderPage = () => originalRenderPage({
      enhanceApp: App => props => sheet.collectStyles(<App {...props} />),
    });

    const initialProps = await Document.getInitialProps(ctx);
    return {
      ...initialProps,
      styles: (
        <>
          {initialProps.styles}
          {sheet.getStyleElement()}
        </>
      ),
    };
  } finally {
    sheet.seal();
  }
};
/application/render.js
import Document from 'next/document';
import { ServerStyleSheet } from 'styled-components';

export const extractStyles = async (ctx) => {
    const sheet = new ServerStyleSheet();
    const originalRenderPage = ctx.renderPage;

    try {
        ctx.renderPage = () => originalRenderPage({
            enhanceApp: App => props => sheet.collectStyles(<App {...props} />),
        });

        const initialProps = await Document.getInitialProps(ctx);
        return {
            ...initialProps,
            styles: (
                <>
                    {initialProps.styles}
                    {sheet.getStyleElement()}
                </>
            ),
        };
    } finally {
        sheet.seal();
    }
};

Cambiar dinámicamente el title de la página en la que estamos

Necesitaremos instalar react-helmet. Esta librería permite cargar en el head de la página cualquier tipo de etiqueta.

npm i react-helmet

Para usarla, debemos cargar el módulo correspondiente en cada página:

import Helmet from 'react-helmet';

export default () => (
    <>
        <Helmet>
            <title>Sillas de bebé para coche</title>
        </Helmet>

Cargar Google Analytics en NextJS

npm i react-ga
/application/tracking.js
import { useEffect } from 'react';
import ReactGA from 'react-ga';
import { useRouter } from 'next/router';

export default () => {
    const { pathname } = useRouter();

    useEffect(() => {
        ReactGA.initialize('UA-19791121-2');
    }, []);

    useEffect(() => {
        ReactGA.pageview(pathname);
    }, [pathname]);

    return null;
};

Debemos cargar este componente en _app.js:

/pages/_apps.js
import { GlobalStyle } from '../application/styled';
import NavBar from '../components/navbar';
import Tracking from '../application/tracking';

function MyApp({ Component, pageProps }) {
  return <>
    <GlobalStyle />
    <Tracking />
    <NavBar />
    <Component {...pageProps} />
  </>
}

export default MyApp

Problema con el underscore en github

Github no accede correctamente a carpetas que empiezan por guión bajo (_). Para evitar este problema, debemos añadir un fichero llamado .nojekyll dentro de la carpeta donde estamos compilando (dist o docs según el caso). Esto es necesario en nextJS ya que nextJS utiliza una carpeta llamada _next.

← Reordenar elementos con Drag & Drop
Extras de React →