✨ Next.js 14
Tags: nextjs, webdev, javascript, programming
Published: 2023-11-11 21:21:05

Como se anunció en la Next.js Conf, Next.js 14 es una versión más enfocada en:

- Turbopack: 5,000 pruebas pasadas para App & Pages Router.
Inicio de servidor local un 53% más rápido.
Actualizaciones de código un 94% más rápidas con Fast Refresh.
- Acciones en el Servidor (Server Actions): Mutaciones mejoradas de forma progresiva.
Integrado con caché y revalidación.
Llamadas de funciones simples o funciona nativamente con formularios.
- Prerenderización Parcial (Experimental): Respuesta estática inicial rápida + contenido dinámico en streaming.
- Next.js Learn (Nuevo curso): Curso gratuito que enseña el App Router, autenticación, bases de datos y más.

Actualiza hoy o comienza con:

```
npx create-next-app@latest
```

## Compilador de Next.js: Turbopack
Desde Next.js 13, se ha estado trabajando arduamente para mejorar el rendimiento del desarrollo local tanto en Next.js en sus páginas como en el App Router.

Anteriormente, se estaba rescribiendo next dev y otras partes de Next.js para respaldar este esfuerzo. Desde entonces, se ha cambiado la aproximación para ser más incremental. Esto significa que el compilador basado en Rust alcanzará la estabilidad pronto, ya que se han centrado en respaldar todas las características de Next.js primero.

5,000 pruebas de integración para next dev están pasando ahora con Turbopack, el motor subyacente en Rust. Estas pruebas incluyen 7 años de correcciones de errores y reproducciones.

Mientras se realizaban pruebas en vercel.com, una gran aplicación de Next.js, se han observado:

- 53.3% más rápido en cuanto al inicio del servidor local.
- 94.7% más rápida en cuanto a la actualización de código con Fast Refresh.

Este benchmark es un resultado práctico de las mejoras de rendimiento que deberías esperar con una aplicación grande (y un gráfico de módulos grande). Con un 90% de pruebas para next dev pasando ahora, deberías experimentar un rendimiento más rápido y confiable de manera constante al usar next dev --turbo.

Una vez que alcancen el 100% de pruebas pasando, se movera Turbopack a la versión estable en una próxima versión menor. También se continuarán respaldando el uso de webpack para configuraciones personalizadas y complementos del ecosistema.

Puedes seguir el porcentaje de pruebas pasando en areweturboyet.com.

## Forms y Mutations
Next.js 9 introdujo las Rutas de API, una forma de construir rápidamente endpoints de backend junto con tu código frontend.

Por ejemplo, podrías crear un nuevo archivo en el directorio api/:

```
// pages/api/submit.ts

import type { NextApiRequest, NextApiResponse } from 'next';
 
export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse,
) {
  const data = req.body;
  const id = await createItem(data);
  res.status(200).json({ id });
}
```

Luego, en el lado del cliente, podrías usar React y un manejador de eventos como onSubmit para hacer una solicitud a tu Ruta de API.

```
// pages/index.tsx

import { FormEvent } from 'react';
 
export default function Page() {
  async function onSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
 
    const formData = new FormData(event.currentTarget);
    const response = await fetch('/api/submit', {
      method: 'POST',
      body: formData,
    });
 
    // Handle response if necessary
    const data = await response.json();
    // ...
  }
 
  return (
    <form onSubmit={onSubmit}>
      <input type="text" name="name" />
      <button type="submit">Submit</button>
    </form>
  );
}
```

Ahora, con Next.js 14, se quiere simplificar la experiencia del desarrollador al crear mutaciones de datos. Además, se quiere mejorar la experiencia del usuario cuando este tiene una conexión de red lenta o cuando envía un formulario desde un dispositivo de menor potencia.

## Server Actions
¿Y si no necesitaras crear manualmente una Ruta de API? En su lugar, podrías definir una función que se ejecute de manera segura en el servidor, llamada directamente desde tus componentes React.

```
// app/page.tsx

export default function Page() {
  async function create(formData: FormData) {
    'use server';
    const id = await createItem(formData);
  }
 
  return (
    <form action={create}>
      <input type="text" name="name" />
      <button type="submit">Submit</button>
    </form>
  );
}
```

Las Server Actions deberían resultar familiares para cualquier desarrollador que haya utilizado frameworks centrados en el servidor en el pasado. Está basado en fundamentos web como formularios y la API web FormData.

Si bien usar Server Actions a través de un formulario es útil para la mejora progresiva, no es un requisito. También puedes llamarlas directamente como una función, sin un formulario. Al utilizar TypeScript, esto te proporciona una seguridad de tipos de extremo a extremo entre el cliente y el servidor.

La mutación de datos, la actualización de la página o la redirección pueden ocurrir en una sola solicitud de red, asegurando que se muestren los datos correctos en el cliente, incluso si el proveedor upstream es lento. Además, puedes componer y reutilizar diferentes acciones, incluyendo muchas acciones diferentes en la misma ruta.

## Caché, Revalidación, Redirección y Más
Las Server Actions están profundamente integradas en todo el modelo del App Routers. Puedes:

- Revalidar datos en caché con revalidatePath() o revalidateTag().
- Redireccionar a rutas diferentes a través de redirect().
- Establecer y leer cookies a través de cookies().
- Manejar actualizaciones optimistas de la interfaz de usuario con useOptimistic().
- Capturar y mostrar errores del servidor con useFormState().
- Mostrar estados de carga en el cliente con useFormStatus().

Obtén más información sobre Forms y Mutations con Server Actions o sobre el modelo de seguridad y las mejores prácticas para Componentes en el Servidor y Acciones en el Servidor.

## Prerenderización Parcial (Partial Pre-rendering)
Se compartió una vista previa del Prerenderización Parcial, una optimización del compilador para contenido dinámico con una respuesta estática inicial rápida, en la que se está trabajando para Next.js.

```
// app/page.tsx

export default function Page() {
  return (
    <main>
      <header>
        <h1>My Store</h1>
        <Suspense fallback={<CartSkeleton />}>
          <ShoppingCart />
        </Suspense>
      </header>
      <Banner />
      <Suspense fallback={<ProductListSkeleton />}>
        <Recommendations />
      </Suspense>
      <NewProducts />
    </main>
  );
}
```

Con la Prerenderización Parcial habilitada, esta página genera una estructura estática basada en tus límites de <Suspense />. El fallback de React Suspense se prerrenderiza.

Los fallbacks de Suspense en la estructura estática se reemplazan luego con componentes dinámicos, como la lectura de cookies para determinar el carrito o mostrar un banner basado en el usuario.

Cuando se realiza una solicitud, la estructura HTML estática se sirve de inmediato:

```
<main>
  <header>
    <h1>My Store</h1>
    <div class="cart-skeleton">
      <!-- Hole -->
    </div>
  </header>
  <div class="banner" />
  <div class="product-list-skeleton">
    <!-- Hole -->
  </div>
  <section class="new-products" />
</main>
```

Dado que <ShoppingCart /> lee cookies para examinar la sesión del usuario, este componente se transmite como parte de la misma solicitud HTTP que la estructura estática. No se necesitan rondas de red adicionales.

```
// app/cart.tsx

import { cookies } from 'next/headers'
 
export default function ShoppingCart() {
  const cookieStore = cookies()
  const session = cookieStore.get('session')
  return ...
}
```

Para tener la estructura estática más granular posible, esto puede requerir agregar límites de Suspense adicionales. Sin embargo, si ya estás utilizando loading.js hoy, este es un límite de Suspense implícito, por lo que no se requerirían cambios para generar la estructura estática.

## Próximamente
La prerrenderización parcial está en desarrollo activo. Compartiremos más actualizaciones en una próxima versión menor.

**Mejoras en Metadatos**
Antes de que el contenido de tu página pueda transmitirse desde el servidor, es importante enviar metadatos sobre la ventana gráfica, el esquema de colores y el tema al navegador primero.

En Next.js 14, hemos separado los metadatos bloqueantes y no bloqueantes. Solo un pequeño subconjunto de opciones de metadatos son bloqueantes, y queremos asegurarnos de que los metadatos no bloqueantes no impidan que una página parcialmente prerrenderizada sirva la estructura estática.

Las siguientes opciones de metadatos ahora están en desuso y se eliminarán de los metadatos en una futura versión principal:

- viewport: Establece el zoom inicial y otras propiedades de la ventana gráfica.
- colorScheme: Establece los modos admitidos (claro/oscuro) para la ventana gráfica.
- themeColor: Establece el color que debería mostrar el cromo alrededor de la ventana gráfica.

A partir de Next.js 14, existen nuevas opciones viewport y generateViewport para reemplazar estas opciones. Todas las demás opciones de metadatos permanecen iguales.

Puedes comenzar a adoptar estas nuevas API hoy. Las opciones de metadatos existentes seguirán funcionando.