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….
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.