Las aplicaciones de una sola página (SPA) se han convertido en la forma moderna de crear aplicaciones web, e Inertia.js es una herramienta líder que permite a los desarrolladores crear SPA con renderización tanto del lado del cliente como del lado del servidor.

En este artículo, veremos cómo Inertia hace que construir SPAs sea un juego de niños y cómo resuelve muchos otros problemas para los desarrolladores. También cubriremos las principales características de la herramienta.

Pero antes de empezar, vamos a asegurarnos de que entendemos cómo funcionan las aplicaciones del lado del servidor y del lado del cliente.

¿Qué Es la Renderización del Lado del Servidor?

La renderización del lado del servidor (SSR) es cuando una aplicación puede renderizar o mostrar el contenido de la página web en el servidor en lugar de en el navegador. Cuando un usuario intenta visitar ejemplo.com, el navegador hace una petición al servidor solicitando toda la información necesaria para mostrar esta página web específica, y el servidor responde instantáneamente proporcionando al navegador una página completamente renderizada.

Los motores de búsqueda intervienen e indexan la información suministrada por el servidor antes de que llegue al navegador; esto se conoce como optimización de motores de búsqueda (SEO). A continuación, el navegador resuelve el contenido de JavaScript, y la página web se muestra al usuario.

Mostrando contenido renderizado en el lado del servidor.
Mostrando contenido renderizado en el lado del servidor.

El problema del enfoque SSR es que se tarda mucho en cargar una página completamente renderizada desde el servidor, lo que no ofrece una experiencia agradable al usuario. Por ello, los desarrolladores consideran las SPA y el renderizado del lado del cliente.

¿Qué Es la Renderización del Lado del Cliente?

La renderización del lado del cliente permite que el navegador tenga todo lo que necesita para renderizar la página web desde el lado del cliente, en lugar de recibir una página completamente renderizada desde el servidor. Cuando se carga la página, el navegador no envía ninguna otra petición al servidor, lo que hace que la experiencia de navegación sea extremadamente rápida.

Visualizando el contenido renderizado en el lado del cliente.
Visualizando el contenido renderizado en el lado del cliente.

El renderizado del lado del cliente ayudó a la creación de las SPA, revolucionando la web. Se puede crear un sitio web que no requiera recargar la página, independientemente de cuántos enlaces se pulsen. Esto facilita al usuario la navegación por el sitio web.

Aunque las SPA son fantásticas, este enfoque tiene mucha complejidad y problemas que vamos a tratar hoy. Inertia aborda la mayoría de estos problemas utilizando eficazmente los frameworks del lado del servidor. Combina las mejores características de las aplicaciones del lado del servidor y del lado del cliente.

¿Qué es Inertia.js?

Inertia no es un framework de JavaScript. En su lugar, es una estrategia o técnica para desarrollar SPAs. Permite al desarrollador utilizar los marcos actuales del lado del servidor para construir una SPA moderna sin la complejidad que conlleva.

Inercia se ha diseñado para acompañar, no para sustituir, a los frameworks que ya utilizas. Considéralo un útil aliado que te ayuda a completar las tareas de forma más rápida y eficiente. Actualmente es compatible con tres frameworks de frontend (Vue, React y Svelte) para la renderización del lado del cliente y con dos frameworks de backend (Laravel y Rails) para la renderización del lado del servidor.

Para la mayoría de los desarrolladores de Laravel, Inertia es una de las técnicas más fiables para construir SPAs, ya que les permite conectar tanto los frameworks de frontend como de backend.

¿Cómo Funciona Inertia.js?

Inertia es similar a Vue Router, en el sentido de que te permite moverte entre páginas sin tener que recargar toda la página. Sin embargo, Inertia funciona en sincronización con tu framework del lado del servidor. Esto es posible con Link, una envoltura para la etiqueta de anclaje estándar. Cuando se hace clic en un Link, Inercia intercepta el evento de clic y envía una petición XHR al servidor, haciendo que éste reconozca que se trata de una petición de Inertia y devuelva una respuesta JSON. Esa respuesta incluye el nombre y los datos del componente JavaScript, tras lo cual Inertia elimina mágicamente los componentes innecesarios y los sustituye por los necesarios para visitar la nueva página y actualiza el estado del historial.

Una inmersión profunda en la funcionalidad de Inertia.js

Cuando un visitante visita inicialmente example.com, el navegador realiza una petición estándar de página completa, y el servidor devuelve una respuesta HTML completa como si no existiera Inercia. Esta respuesta HTML tiene todos los activos del sitio (CSS, JavaScript), pero también contiene un activo extra para Inertia, que es la raíz div con el atributo data-page que contiene datos JSON para la página inicial. Inertia utiliza entonces estos datos JSON para poner en marcha el marco del frontend y mostrar la página inicial.

Inertia.js: Respuesta de la visita a la página inicial.
Inertia.js: Respuesta de la visita a la página inicial.

Una vez iniciada la aplicación, cada ruta que el usuario visite dentro del mismo dominio utilizando Link será una petición XHR con la cabecera X-Inertia. Esto indica al servidor que se trata de una petición de Inercia.

La respuesta vendrá como una respuesta JSON con el contenido de la página, en lugar de una respuesta HTML completa como en la visita inicial.

Inertia.js: Respuesta de la visita de la ruta posterior.
Inertia.js: Respuesta de la visita de la ruta posterior.

¿Qué Problemas Resuelve Inertia.js?

Inertia resuelve un gran número de problemas para los desarrolladores web. El objetivo de crear Inertia era dar soluciones rápidas y eficaces a toda la complejidad que conlleva el diseño de una SPA.

Complejidades de las SPA

Si los desarrolladores construyeran una SPA sin Inertia, tendrían que crear APIs REST o GraphQL y protegerlas con algún tipo de método de autenticación, lo que requeriría la creación de un sistema de gestión de estados en el front-end, entre otras muchas cosas.

Inertia se diseñó para ayudar a los desarrolladores a transformar sus aplicaciones del lado del servidor, que se ejecutan completamente en el servidor backend, en una aplicación JavaScript de una sola página sin tener que pasar por todas las complejidades que conlleva la construcción de SPA.

Crear una SPA con Inertia es similar a crear una aplicación renderizada del lado del servidor. Creas controladores, haces consultas a la base de datos para obtener los datos necesarios y luego devuelves los resultados a las vistas.

La clave aquí es que las vistas son componentes de JavaScript. Esto significa que obtienes los datos de tu servidor, y luego Inertia trabaja con el marco del frontend para mostrar la página que contiene los datos como un archivo JavaScript, eliminando la necesidad de crear APIs.

Autenticación

Como Inertia alimenta la aplicación con datos y respuestas del backend, simplemente utilizará cualquier sistema de autenticación que tengas en el lado del servidor. Esto significa que no tendrás que preocuparte por la autenticación del lado del cliente, sino que tendrás un sistema de autenticación basado en la sesión que se sincroniza con tu sistema de autenticación del lado del servidor.

Problemas de SEO

Como se ha explicado anteriormente para la renderización del lado del servidor, los motores de búsqueda interceptan la respuesta del servidor al navegador para indexar el contenido HTML de la página web. En el caso de una SPA, los motores de búsqueda tendrán dificultades para identificar el contenido de la página, ya que el servidor responderá con componentes JavaScript y datos JSON.

Pero Inertia ha resuelto este problema introduciendo la función de renderización del lado del servidor (SSR) que puedes añadir a tu aplicación. Inertia utiliza el entorno Node.js como disparador para convertir la respuesta de datos JSON en HTML.

Para ilustrar mejor esto, imagina a Inertia sentada entre el servidor y el navegador, observando. Cuando el servidor recibe una petición de Inertia y devuelve una respuesta JSON, Inertia detecta la existencia de un servidor Node.js, transforma la respuesta JSON en HTML y la devuelve, permitiendo a los motores de búsqueda indexar la página como si la aplicación no fuera una SPA.

Inertia también proporciona un componente Head, que te permite añadir un título y metadatos a tu página:


<script setup>
import { Head } from '@inertiajs/inertia-vue3'
</script>

<template>
  <Head>
    <title>Page Title</title>
    <meta name="description" content="Page Description" />
  </Head>
</template>

Aquí tienes otro ejemplo de la documentación online de Inertia:


// Layout.vue

import { Head } from '@inertiajs/inertia-vue3'

<Head>
  <title>My app</title>
  <meta head-key="description" name="description" content="This is the default description" />
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
</Head>

// About.vue

import { Head } from '@inertiajs/inertia-vue3'

<Head>
  <title>About - My app</title>
  <meta head-key="description" name="description" content="This is a page specific description" />
</Head>

Formularios y ayudante de formularios

Es posible enviar una solicitud de formulario estándar mientras se utiliza Inertia. Sin embargo, al hacerlo, se actualizará toda la página.

Inertia permite a los usuarios realizar solicitudes de formularios utilizando Inertia, lo que elimina la posibilidad de refrescar la página. Una vez que el formulario se envía con Inercia, se gestiona en el lado del servidor, lo que te permite redirigir al usuario a la misma página (o a una página completamente diferente).

Inercia nos facilita la vida a la hora de crear y enviar formularios. Aquí tienes un ejemplo de cómo puedes usarlo con la API de composición de Vue.js 3:


<script setup>
  import { useForm } from "@inertiajs/inertia-vue3";

  const form = useForm({
    email: null,
    password: null,
  });
</script>

<template>
  <form @submit.prevent="form.post('kinsta/login')">
    
    <input type="text" v-model="form.email" />
    
    <input type="password" v-model="form.password" />
    
    <button type="submit">Login</button>
  </form>
</template>

Puedes enviar el formulario con GET, POST, PUT, PATCH y DELETE.


<script setup>
  import { useForm } from "@inertiajs/inertia-vue3";

  const form = useForm({
    email: null,
    password: null,
  });

  const submit = () => {
    form.post("kinsta/login");
  };
</script>

<template>
  <form @submit.prevent="submit()">
    
    <input type="text" v-model="form.email" />
    
    <input type="password" v-model="form.password" />
    
    <button type="submit">Login</button>
  </form>
</template>

El ayudante de formulario de Inertia también ofrece algunas propiedades útiles como la propiedad processing que se convierte en true una vez que el formulario comienza a procesarse. Esto puede usarse para desactivar los botones de envío mientras el formulario se está procesando para evitar múltiples envíos:


<button type="submit" :disabled="form.processing">Submit</button>

También puedes utilizar preserveState, preserveScroll y devoluciones de llamada de eventos con el formulario, lo que será útil cuando añadas opciones adicionales al formulario:


form.post('kinsta/login, {
  preserveScroll: true,
  onSuccess: () => form.reset('password'),
})

Recordar el estado con Inertia.js

Supongamos que un usuario está rellenando un formulario en tu sitio web y decide navegar a otra página antes de enviarlo. Cuando regrese a la página del formulario, se restablecerá la entrada del formulario del usuario.

Afortunadamente, Inertia proporciona la función useRemember, que te permite guardar las entradas del formulario del usuario en el estado de historia y restaurarlas en la navegación de historia.

Puedes utilizar esta función importándola de Inertia y aplicándola a tu formulario:


import { useRemember } from '@inertiajs/inertia-vue3'

export default {
  setup() {
    const form = useRemember({
        first_name: null,
        last_name: null,
    })

    return { form }
  },
}

Si tienes una página con muchos formularios que utilizan la función useRemember, cada componente debe tener una clave única para que Inertia sepa qué datos debe restaurar en cada componente:


const form = useRemember({
        first_name: null,
        last_name: null,
    }, 'Users/Create')

No es necesario utilizar la función useRemember cuando se utiliza el ayudante de formularios de Inertia. Inertia recordará el estado de la entrada del formulario de forma automática, por lo que sólo tenemos que darle un identificador único:


import { useForm } from '@inertiajs/inertia-vue3'

const form = useForm('CreateUser', data)

Lo bueno de esta funcionalidad es que puedes recordar manualmente cualquier dato de tu aplicación. Esto también puede ser útil para pasar datos de un componente profundamente anidado al componente principal:


import { Inertia } from '@inertiajs/inertia'

// DeeplyNestedComponent.vue
Inertia.remember(data, 'my-key')

// MainComponent.vue
let data = Inertia.restore('my-key')

Carga de archivos

Inercia detecta si el formulario incluye archivos y, si es así, transforma los datos de la solicitud en el objeto formData, que siempre es necesario. Así que si tienes un formulario que incluye un nombre y un avatar, Inertia tratará el formulario como multipart/form-data.

Validación y errores

Cuando un usuario envía un formulario con valores incorrectos y se envía al servidor para su validación, devuelve al usuario a la página del formulario con un flash de errores de validación en la sesión. Inercia captura los errores de la sesión y los guarda como accesorios de la página.

Como los props son reactivos, aparecen cuando se completa el envío del formulario. Para que Inercia detecte la existencia de errores, vigila page.props.errors.

Una vez que ha encontrado errores, proporciona una llamada de retorno a onError() en lugar de onSuccess().

Aquí tienes un ejemplo con Vue 3 para ayudarte a entender el concepto:


const submit = () => {
    form.post("kinsta/login", {
        onError: () => {
            return "Hi! , the server returned an error and Inertia saved it as a prop. Do as you like with me"
        },
        onSuccess: () => {
            return "Wohoo!!"
        }
    }
    );
  };

Mostrar los errores es tan fácil como definirlos como props y mostrarlos condicionalmente en tu HTML:


<script setup>
  defineProps({
    errors: Object,
  });

//
</script>

<template>
  <form @submit.prevent="submit()">
    //
    <div v-if="errors.email">{{ errors.email }}</div>
  </form>
</template>

Al utilizar Inercia, no tienes que preocuparte por los datos de entrada antiguos en caso de errores. Una vez que Inercia detecta que el usuario ha sido redirigido a la página con errores, conserva automáticamente el estado antiguo del componente para POST, PUT, PATCH y DELETE.

Recargas parciales con Inertia.js

La funcionalidad de recarga parcial de Inertia es simplemente excelente, ya que sólo recarga un componente seleccionado en la página, en lugar de volver a obtener todo el conjunto de datos del servidor. Esto lleva la optimización de tu aplicación al siguiente nivel. También puedes visitar el siguiente enlace para saber más sobre cómo optimizar el rendimiento de tu aplicación Laravel.

Se pueden realizar recargas parciales utilizando la propiedad only de Inertia:


import { Inertia } from '@inertiajs/inertia'

Inertia.visit(url, {
  only: ['users'],
})

Redirecciones externas con Inertia.js

El enrutamiento de subdominios, o redireccionamiento externo, es uno de los retos más frustrantes de las SPA. Es irracional esperar que tu aplicación siga siendo una aplicación de una sola página mientras visita un dominio diferente.

Puede ser necesario redirigir una petición de Inertia a un sitio web externo o incluso a otro punto final no perteneciente a Inertia en tu aplicación. Esto es posible mediante una visita iniciada por el servidor window.location:


return Inertia::location($url);

Si abres la consola mientras pruebas esto, verás que devuelve 409 conflict. Esta respuesta contiene la URL en la cabecera X-Inertia-Location, que Inertia detectará en el lado del cliente y realizará automáticamente la visita.

Cómo Trabajar con Inertia.js

Trabajar con Inertia es similar a trabajar en una aplicación del lado del servidor, con la excepción de que es una aplicación de una sola página totalmente reactiva. Deberías ser capaz de definir tus rutas, personalizar los controladores y devolver una vista para que Inertia la envíe a tu framework de frontend.

Rutas de Laravel e Inertia.js

El enrutamiento de Laravel no es algo a lo que quieras renunciar cuando desarrolles tu aplicación; te permite construir rápidamente las rutas más complejas, y hay un montón de recursos de Laravel gratuitos y de pago que pueden ayudarte a aprender más sobre Laravel y cómo funciona el enrutamiento.

Lo bueno aquí es que no necesitas Vue Router o React Router para llevar a cabo un enrutamiento simple del lado del cliente, porque Inertia tiene su propio sistema de enrutamiento que funciona con el de Laravel. Si el trabajo no requiere ningún dato del backend, puedes utilizar el ayudante del enrutador para enrutar directamente a un componente.


Route::inertia('/home', 'HomeComponent');

public function index()
    {
    return Inertia::render('Users/Index', [
        'users' => User::all();
        'create_url' => URL::route('users.create'),
    ]);
}

Antes de continuar, nos gustaría presentarte DevKinsta, una potente herramienta para desarrolladores, diseñadores y agencias que les permite construir aplicaciones web de WordPress de una o varias páginas. Afortunadamente, WordPress puede integrarse con Laravel utilizando el paquete Corcel. Si construyes una aplicación Laravel con integración de WordPress, echa un vistazo a la herramienta Kinsta APM para una extraordinaria monitorización del rendimiento.

Redirecciones

Siempre debes redirigir al usuario a la ruta correcta que corresponde a la solicitud inicial. Por ejemplo, si un usuario está enviando a store endpoint para enviar un post, asegúrate de redirigir al cliente a GET endpoint quizás a la ruta del post.


public function store()
{
    Post::create(
        Request::validate([
            'title' => ['required'],
            'body' => ['required'],
        ])
    );

    // redirect the user to the posts show page
    return Redirect::route('posts.show');
}

Desventajas del Uso de Inertia.js

Hasta ahora, nos hemos centrado en las diversas ventajas de utilizar Inertia. Sin embargo, como cualquier herramienta, Inertia también tiene desventajas.

  • El usuario debe tener conocimientos básicos de Vue o React.
  • Dado que los datos del modelo pueden pasarse completamente al lado del cliente, el usuario debe asegurarse de devolver explícitamente los datos relevantes al frontend.
  • Las APIs deben ser recreadas si la aplicación web va a tener una aplicación Android o iOS en algún momento.

¿Deberías Utilizar Inertia.js?

Para responder a la pregunta de si debes o no utilizar Inertia, la respuesta es sí, si quieres construir una aplicación moderna de una sola página, del lado del servidor y orientada al SEO.

Puedes obtener más información visitando el sitio web oficial de Inertia.js y leyendo la documentación.

Resumen

Las aplicaciones del lado del cliente y las SPA son cada vez más populares a medida que evolucionan las tecnologías web, mientras que las aplicaciones tradicionales del lado del servidor han empezado a quedarse en el camino. Ahora más que nunca, es importante tener a mano las herramientas adecuadas.

Inertia es un fantástico enfoque o solución moderna para que los desarrolladores del lado del servidor construyan aplicaciones de una sola página. Resuelve muchos problemas y ahorra mucho tiempo.

Como ya comentamos en nuestro artículo, Inertia admite ahora el renderizado del lado del servidor, lo que lo lleva a un nivel completamente nuevo al permitir a los desarrolladores crear SPA impulsadas por el SEO.

Inertia también está recibiendo mucho amor de la comunidad. El esfuerzo de desarrollo está patrocinado por Laravel Forge, Laracasts, y un número de otras buenas organizaciones. Como resultado, Inertia es una herramienta fiable que se mejorará y mantendrá en el futuro para los desarrolladores de Laravel, sobre todo porque la demanda de codificadores de Laravel sigue creciendo.

Y si estás buscando el próximo hogar para tu proyecto impulsado por Intertia, echa un vistazo a las ofertas de alojamiento de aplicaciones de Kinsta.