Saltar al contenido

Migrar desde Gatsby

Aquí hay algunos conceptos clave y estrategias de migración para ayudarte a empezar. ¡Usa el resto de nuestra documentación y nuestra comunidad de Discord para seguir adelante!

Gatsby y Astro comparten algunas similitudes que te ayudarán a migrar tu proyecto:

Cuando reconstruyas tu sitio de Gatsby en Astro, notarás algunas diferencias importantes:

  • Los proyectos de Gatsby son single-page apps de React y usan index.js como raíz de tu proyecto. Los proyectos de Astro son sitios multi-página, e index.astro es tu página de inicio.

  • Los componentes de Astro no se escriben como funciones exportadas que devuelven plantillas de página. En su lugar, dividirás tu código en un “code fence” para tu JavaScript y un body exclusivamente para el HTML que generas.

  • Datos de archivos locales: Gatsby usa GraphQL para recuperar datos de los archivos de tu proyecto. Astro usa imports ESM y funciones top-level await (p. ej. import.meta.glob(), getCollection()) para importar datos de los archivos de tu proyecto. Puedes añadir GraphQL manualmente a tu proyecto de Astro pero no está incluido por defecto.

Cada migración de proyecto será diferente, pero hay algunas acciones comunes que realizarás al convertir de Gatsby a Astro.

Usa el comando create astro de tu gestor de paquetes para lanzar el asistente CLI de Astro o elige un tema de la comunidad del Astro Theme Showcase.

Puedes pasar un argumento --template al comando create astro para iniciar un nuevo proyecto de Astro con uno de nuestros starters oficiales (p. ej. docs, blog, portfolio). O, puedes iniciar un nuevo proyecto desde cualquier repositorio existente de Astro en GitHub.

Ventana de la terminal
# launch the Astro CLI Wizard
npm create astro@latest
# create a new project with an official example
npm create astro@latest -- --template <example-name>

Luego, copia los archivos existentes de tu proyecto de Gatsby a tu nuevo proyecto de Astro en una carpeta separada fuera de src.

Puede que te resulte útil instalar algunas de las integraciones opcionales de Astro para usar mientras conviertes tu proyecto de Gatsby a Astro:

  • @astrojs/react: para reutilizar algunos componentes de UI de React existentes en tu nuevo sitio de Astro o seguir escribiendo con componentes de React.

  • @astrojs/mdx: para traer archivos MDX existentes de tu proyecto de Gatsby, o para usar MDX en tu nuevo sitio de Astro.

Siguiendo la estructura de proyecto de Astro:

  1. Elimina la carpeta public/ de Gatsby.

    Gatsby usa el directorio public/ para su salida de build, así que puedes descartar esta carpeta de forma segura. Ya no necesitarás una versión construida de tu sitio de Gatsby. (Astro usa dist/ por defecto para la salida del build.)

  2. Renombra la carpeta static/ de Gatsby a public/, y úsala como carpeta public/ de Astro.

    Astro usa una carpeta llamada public/ para assets estáticos. Alternativamente, puedes copiar el contenido de static/ en tu carpeta public/ existente de Astro.

  3. Copia o mueve otros archivos y carpetas de Gatsby (p. ej. components, pages, etc.) según sea necesario a tu carpeta src/ de Astro mientras reconstruyes tu sitio, siguiendo la estructura de proyecto de Astro.

    La carpeta src/pages/ de Astro es una carpeta especial usada para enrutamiento basado en archivos para crear las páginas y posts de tu sitio desde archivos .astro, .md y .mdx. No tendrás que configurar ningún comportamiento de enrutamiento para tus archivos de Astro, Markdown, y MDX.

    Todas las demás carpetas son opcionales, y puedes organizar el contenido de tu carpeta src/ como quieras. Otras carpetas comunes en proyectos de Astro incluyen src/layouts/, src/components, src/styles, y src/scripts.

Aquí hay algunos tips para convertir un componente .js de Gatsby en un componente .astro:

  1. Usa solo el return() de la función del componente de Gatsby existente como tu plantilla HTML.

  2. Cambia cualquier sintaxis de Gatsby o JSX a sintaxis de Astro o a estándares web de HTML. Esto incluye <Link to="">, {children}, y className, por ejemplo.

  3. Mueve cualquier JavaScript necesario, incluyendo declaraciones de importación, a un “code fence” (---). Nota: JavaScript para renderizar contenido condicionalmente a menudo se escribe directamente dentro de la plantilla HTML en Astro.

  4. Usa Astro.props para acceder a cualquier prop adicional que se pasara previamente a tu función de Gatsby.

  5. Decide si algún componente importado también necesita convertirse a Astro. Con la integración oficial de React instalada, puedes usar componentes de React existentes en tus archivos de Astro. Pero, puede que quieras convertirlos a componentes .astro, ¡especialmente si no necesitan ser interactivos!

  6. Elimina cualquier consulta de GraphQL. En su lugar, usa declaraciones import y import.meta.glob() para consultar tus archivos locales.

Ve un ejemplo de la plantilla de inicio de Blog de Gatsby convertida paso a paso

Compara el siguiente componente de Gatsby y un componente de Astro correspondiente:

component.jsx
import * as React from "react"
import { useStaticQuery, graphql } from "gatsby"
import Header from "./header"
import Footer from "./footer"
import "./layout.css"
const Component = ({ message, children }) => {
const data = useStaticQuery(graphql`
query SiteTitleQuery {
site {
siteMetadata {
title
}
}
}
`)
return (
<>
<Header siteTitle={data.site.siteMetadata.title} />
<div style={{ margin: `0`, maxWidth: `960`}}>{message}</div>
<main>{children}</main>
<Footer siteTitle={data.site.siteMetadata} />
</>
)
}
export default Component

Puede que te resulte útil comenzar convirtiendo tus layouts y plantillas de Gatsby en componentes de layout de Astro.

Cada página de Astro requiere explícitamente que las etiquetas <html>, <head>, y <body> estén presentes, así que es común reutilizar un archivo de layout entre páginas. Astro usa un <slot /> en lugar de la prop {children} de React para el contenido de la página, sin necesidad de declaración de import. Tu layout.js y plantillas de Gatsby no incluirán estos.

Ten en cuenta las plantillas HTML estándar, y el acceso directo a <head>:

src/layouts/Layout.astro
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<title>Astro</title>
</head>
<body>
<!-- Wrap the slot element with your existing layout templating -->
<slot />
</body>
</html>

También puedes querer reutilizar código del src/components/seo.js de Gatsby para incluir metadatos adicionales del sitio. Ten en cuenta que Astro no usa <Helmet> ni <Header> sino que crea <head> directamente. Puedes importar y usar componentes, incluso dentro de <head>, para separar y organizar el contenido de tu página.

En Gatsby, tus páginas y posts pueden existir en src/pages/ o fuera de src en otra carpeta, como content. En Astro, todo el contenido de tus páginas debe vivir dentro de src/ a menos que uses content collections.

Tus páginas JSX (.js) de Gatsby existentes necesitarán ser convertidas de archivos JSX a páginas .astro. No puedes usar un archivo de página JSX existente en Astro.

Estas páginas .astro deben estar ubicadas dentro de src/pages/ y tendrán rutas de página generadas automáticamente basadas en su ruta de archivo.

Astro tiene soporte integrado para Markdown y una integración opcional para archivos MDX. Tus archivos Markdown y MDX existentes pueden reutilizarse pero pueden requerir algunos ajustes en su frontmatter, como añadir la propiedad especial de frontmatter layout de Astro. También pueden colocarse dentro de src/pages/ para aprovechar el enrutamiento automático basado en archivos.

Alternativamente, puedes usar content collections en Astro para almacenar y gestionar tu contenido. Recuperarás el contenido tú mismo y generarás esas páginas dinámicamente.

Como Astro devuelve HTML crudo, es posible escribir tests end-to-end usando la salida del paso de build. Cualquier test end-to-end escrito previamente podría funcionar out-of-the-box si has podido igualar el markup del sitio antiguo de Gatsby. Librerías de testing como Jest y React Testing Library pueden importarse y usarse en Astro para testear tus componentes de React.

Consulta la guía de testing de Astro para más.

Gatsby tiene varios archivos de configuración de nivel superior que también incluyen metadatos del sitio y de la página y se usan para enrutamiento. No usarás ninguno de estos archivos gatsby-*.js en tu proyecto de Astro, pero puede haber algún contenido que puedas reutilizar mientras construyes tu proyecto de Astro:

  • gatsby-config.js: Mueve tu siteMetadata: {} a src/data/siteMetadata.js (o siteMetadata.json) para importar datos sobre tu sitio (título, descripción, cuentas sociales, etc.) a los layouts de página.

  • gatsby-browser.js: Considera añadir cualquier cosa usada aquí directamente en la etiqueta <head> de tu layout principal.

  • gatsby-node.js: No necesitarás crear tus propios nodos en Astro, pero ver el schema en este archivo puede ayudarte a definir tipos en tu proyecto de Astro.

  • gatsby-ssr.js: Si eliges usar SSR en Astro, añadirás y configurarás el adaptador SSR de tu elección directamente en astro.config.mjs.

Los siguientes son algunos ejemplos de sintaxis específica de Gatsby que necesitarás convertir a Astro. Consulta más diferencias entre Astro y JSX en la guía de escritura de componentes de Astro.

Convierte cualquier componente de Gatsby <Link to="">, <NavLink> etc. a etiquetas HTML <a href="">.

<Link to="/blog">Blog</Link>
<a href="/blog">Blog</a>

Astro no usa ningún componente especial para links, aunque eres libre de construir tu propio componente <Link>. Luego puedes importar y usar este <Link> igual que cualquier otro componente.

src/components/Link.astro
---
const { to } = Astro.props
---
<a href={to}><slot /></a>

Si es necesario, actualiza cualquier importación de archivos para referenciar rutas de archivos relativas exactamente. Esto se puede hacer usando alias de importación, o escribiendo una ruta relativa completa.

Ten en cuenta que los archivos .astro y varios otros tipos de archivo deben importarse con su extensión completa.

src/pages/authors/Fred.astro
---
import Card from `../../components/Card.astro`;
---
<Card />

Convierte cualquier instancia de {children} a un <slot /> de Astro. Astro no necesita recibir {children} como una prop de función y renderizará automáticamente el contenido hijo en un <slot />.

src/components/MyComponent
---
---
export default function MyComponent(props) {
return (
<div>
{props.children}
</div>
);
}
<div>
<slot />
</div>

Los componentes de React que pasan múltiples conjuntos de children se pueden migrar a un componente de Astro usando named slots.

Ve más sobre uso específico de <slot /> en Astro.

Puede que necesites reemplazar cualquier librería CSS-in-JS (p. ej. styled-components) con otras opciones de CSS disponibles en Astro.

Si es necesario, convierte cualquier objeto de estilo inline (style={{ fontWeight: "bold" }}) a atributos de estilo HTML inline (style="font-weight:bold;"). O, usa una etiqueta <style> de Astro para estilos CSS scoped.

src/components/Card.astro
<div style={{backgroundColor: `#f4f4f4`, padding: `1em`}}>{message}</div>
<div style="background-color: #f4f4f4; padding: 1em;">{message}</div>

Tailwind es soportado después de instalar el plugin de Vite de Tailwind. ¡No se requieren cambios a tu código de Tailwind existente!

El styling global se logra en Gatsby usando imports de CSS en gatsby-browser.js. En Astro, importarás archivos .css directamente en un componente de layout principal para lograr estilos globales.

Ve más sobre estilos en Astro.

Convierte los componentes <StaticImage /> y <GatsbyImage /> de Gatsby a los componentes de integración de imágenes de Astro, o a una etiqueta HTML estándar <img> / JSX <img /> según corresponda en tus componentes de React.

src/pages/index.astro
---
import { Image } from 'astro:assets';
import rocket from '../assets/rocket.png';
---
<Image src={rocket} alt="A rocketship in space." />
<img src={rocket.src} alt="A rocketship in space.">

El componente <Image /> de Astro funciona solo en archivos .astro y .mdx. Consulta una lista completa de sus atributos de componente y ten en cuenta que varios diferirán de los atributos de Gatsby.

Para continuar usando imágenes en archivos Markdown (.md) usando sintaxis Markdown estándar (![]()), puede que necesites actualizar el enlace. Usar la etiqueta HTML <img> directamente no está soportado en archivos .md para imágenes locales, y debe convertirse a sintaxis Markdown.

src/pages/post-1.md
# My Markdown Page
<!-- Local image stored at src/assets/stars.png -->
![A starry night sky.](../assets/stars.png)

En componentes de React (.jsx), usa sintaxis de imagen JSX estándar (<img />). Astro no optimizará estas imágenes, pero puedes instalar y usar paquetes NPM para más flexibilidad.

Puedes aprender más sobre el uso de imágenes en Astro en la guía de Images.

Elimina todas las referencias a consultas de GraphQL, y en su lugar usa import.meta.glob() para acceder a datos de tus archivos locales.

O, si usas content collections, consulta tus archivos Markdown y MDX usando getEntry() y getCollection().

Estas solicitudes de datos se hacen en el frontmatter del componente de Astro usando los datos.

src/pages/index.astro
---
import { graphql } from "gatsby"
import { getCollection } from 'astro:content';
// Get all `src/content/blog/` entries
const allBlogPosts = await getCollection('blog');
// Get all `src/pages/posts/` entries
const allPosts = Object.values(import.meta.glob('../pages/post/*.md', { eager: true }));
---
export const pageQuery = graphql`
{
allMarkdownRemark(sort: { frontmatter: { date: DESC } }) {
nodes {
excerpt
fields {
slug
}
frontmatter {
date(formatString: "MMMM DD, YYYY")
title
description
}
}
}
}
`

Este ejemplo convierte el layout principal del proyecto (layout.js) del starter de blog de Gatsby a src/layouts/Layout.astro.

Este layout de página muestra un header cuando se visita la página de inicio, y un header diferente con un enlace de vuelta a Home para todas las demás páginas.

  1. Identifica el JSX del return().

    layout.js
    import * as React from "react"
    import { Link } from "gatsby"
    const Layout = ({ location, title, children }) => {
    const rootPath = `${__PATH_PREFIX__}/`
    const isRootPath = location.pathname === rootPath
    let header
    if (isRootPath) {
    header = (
    <h1 className="main-heading">
    <Link to="/">{title}</Link>
    </h1>
    )
    } else {
    header = (
    <Link className="header-link-home" to="/">
    Home
    </Link>
    )
    }
    return (
    <div className="global-wrapper" data-is-root-path={isRootPath}>
    <header className="global-header">{header}</header>
    <main>{children}</main>
    <footer>
    © {new Date().getFullYear()}, Built with
    {` `}
    <a href="https://www.gatsbyjs.com">Gatsby</a>
    </footer>
    </div>
    )
    }
    export default Layout
  2. Crea Layout.astro y añade este valor de return, convertido a sintaxis de Astro.

    Ten en cuenta que:

    • {new Date().getFullYear()} simplemente funciona 🎉
    • {children} se convierte en <slot /> 🦥
    • className se convierte en class 📛
    • Gatsby se convierte en Astro 🚀
    src/layouts/Layout.astro
    ---
    ---
    <div class="global-wrapper" data-is-root-path={isRootPath}>
    <header class="global-header">{header}</header>
    <main><slot /></main>
    <footer>
    © {new Date().getFullYear()}, Built with
    {` `}
    <a href="https://www.astro.build">Astro</a>
    </footer>
    </div>
  3. Añade un page shell para que tu layout proporcione a cada página las partes necesarias de un documento HTML:

    src/layouts/Layout.astro
    ---
    ---
    <html>
    <head>
    <meta charset="utf-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="viewport" content="width=device-width" />
    <title>Astro</title>
    </head>
    <body>
    <div class="global-wrapper" data-is-root-path={isRootPath}>
    <header class="global-header">{header}</header>
    <main>
    <slot />
    </main>
    <footer>
    &#169; {new Date().getFullYear()}, Built with
    {` `}
    <a href="https://www.astro.build">Astro</a>
    </footer>
    </div>
    </body>
    </html>
  4. Añade cualquier import, prop y JavaScript necesario

    Para renderizar condicionalmente un header basado en la ruta y el título de la página en Astro:

    • Proporciona las props vía Astro.props. (Recuerda: tu plantilla de Astro accede a las props desde su frontmatter, no pasadas a una función.)
    • Usa un operador ternario para mostrar un heading si esta es la página de inicio, y un heading diferente en caso contrario.
    • Elimina las variables para {header} e {isRootPath} ya que no son necesarias.
    • Reemplaza las etiquetas <Link/> de Gatsby con etiquetas de ancla <a>.
    • Usa class en lugar de className.
    • Importa una hoja de estilo local de tu proyecto para que los nombres de clase surtan efecto.
    src/layouts/Layout.astro
    ---
    import '../styles/style.css';
    const { title, pathname } = Astro.props
    ---
    <html>
    <head>
    <meta charset="utf-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="viewport" content="width=device-width" />
    <title>Astro</title>
    </head>
    <body>
    <div class="global-wrapper">
    <header class="global-header">
    { pathname === "/"
    ?
    <h1 class="main-heading">
    <a href="/">{title}</a>
    </h1>
    :
    <h1 class="main-heading">
    <a class="header-link-home" href="/">Home</a>
    </h1>
    }
    </header>
    <main>
    <slot />
    </main>
    <footer>
    &#169; {new Date().getFullYear()}, Built with
    {` `}
    <a href="https://www.astro.build">Astro</a>
    </footer>
    </div>
    </body>
    </html>
  5. Actualiza index.astro para usar este nuevo layout y pasarle las props necesarias de title y pathname:

    src/pages/index.astro
    ---
    import Layout from '../layouts/Layout.astro';
    const pagePathname = Astro.url.pathname
    ---
    <Layout title="Home Page" pathname={pagePathname}>
    <p>Astro</p>
    </Layout>
  6. Para testear el header condicional, crea una segunda página, about.astro usando el mismo patrón:

    src/pages/about.astro
    ---
    import Layout from '../layouts/Layout.astro';
    const pagePathname = Astro.url.pathname
    ---
    <Layout title="About" pathname={pagePathname}>
    <p>About</p>
    </Layout>

    Deberías ver un enlace a "Home" solo cuando visites la página About.

Más guías de migración

Contribuir Comunidad Patrocinar