コンテンツにスキップ

Gatsbyからの移行

ここでは、移行を始める際に役立つ主要な概念と移行戦略を紹介します。詳しくはドキュメント全体やDiscordコミュニティをご活用ください。

GatsbyとAstroには、プロジェクト移行を容易にするいくつかの共通点があります:

GatsbyサイトをAstroで再構築する際には、次のような重要な違いに気付くでしょう。

  • GatsbyプロジェクトはReactの単一ページアプリケーションで、index.jsをプロジェクトのルートとして使用します。Astroプロジェクトはマルチページサイトで、index.astroはホームページです。

  • Astroコンポーネントは、ページテンプレートを返すようにexportされた関数で書かれていません。代わりに、コードフェンス(---)でJavaScriptコードを区切って、生成するHTMLのためのコードを分けます。

  • ローカルファイルデータの取得: GatsbyはGraphQLを使用してプロジェクトファイルからデータを取得します。AstroではESMインポートとトップレベルawait関数(例: import.meta.glob()getCollection())でファイルからデータをインポートします。必要ならAstroプロジェクトにGraphQLを手動で追加できますが、デフォルトでは含まれていません。

各プロジェクトの移行手順は様々ですが、GatsbyからAstroへ変換する際に共通して行う作業があります。

パッケージマネージャでcreate astroコマンドを実行してAstroのCLIウィザードを起動するか、Astro Theme Showcaseからコミュニティテーマを選択します。

create astroコマンドに--template引数を渡すと、公式スターター(例:docsblogportfolio)のいずれかで新しいAstroプロジェクトを作成できます。また、GitHub上の既存Astroリポジトリから新規プロジェクトを開始することも可能です。

ターミナルウィンドウ
# Astro CLIウィザードを実行
npm create astro@latest
# 公式スターターを指定して作成
npm create astro@latest -- --template <example-name>

次に、既存のGatsbyプロジェクトのファイルをsrcの外側にある別フォルダーへコピーし、新しいAstroプロジェクトへ移行します。

インテグレーションのインストールする(任意)

セクションタイトル: インテグレーションのインストールする(任意)

GatsbyプロジェクトをAstroへ変換する際、以下のようなAstroのオプションインテグレーションが役立つことがあります。

  • @astrojs/react: 新規Astroサイトで既存のReact UIコンポーネントを再利用するか、Reactコンポーネントで書き続けることができます。

  • @astrojs/mdx: Gatsbyプロジェクトの既存のMDXファイルを持ち込むか、新規AstroサイトでMDXを使用することができます。

Astroのプロジェクト構造に従って、次の手順でファイルを整理します。

  1. 削除 Gatsbyのpublic/フォルダ。

    Gatsbyはビルド出力をpublic/ディレクトリに生成しますが、Astroはデフォルトでdist/を使用します。そのためpublic/は安全に削除できます。

  2. リネーム Gatsbyのstatic/フォルダをpublic/、そしてAstroのpublic/フォルダとして使用してください。

    Astroは静的アセット用にpublic/フォルダーを使用します。既存のAstropublic/static/の内容をコピーしても構いません。

  3. コピーまたは移動 Gatsbyのcomponentspagesなどの他のファイルとフォルダを、必要に応じてAstroのsrc/フォルダへ配置してください。Astroのプロジェクト構造を遵守して、ソースコードをsrcに配置してください。

    Astroのsrc/pages/フォルダは、.astro.md.mdxファイルからサイトのページと記事を生成するための特殊なフォルダです。Astro、Markdown、MDXファイルのルーティングを設定する必要はありません。

    その他のフォルダは任意のため、src/フォルダの内容をどのように配置するかは任意です。Astroプロジェクトで一般的なフォルダにはsrc/layouts/src/componentssrc/stylessrc/scriptsがあります。

ヒント:JSXファイルから.astroファイルへの変換する

セクションタイトル: ヒント:JSXファイルから.astroファイルへの変換する

ここでは、Gatsbyの.jsコンポーネントを.astroコンポーネントに変換するためのいくつかの手順を説明します。

  1. 既存Gatsbyコンポーネントのreturn()部分のみをHTMLテンプレートとして使用してください。

  2. <Link to="">{children}classNameなどGatsby/JSX構文をAstro構文またはHTML標準に変換してください。

  3. import文を含んだ必要なJavaScriptは”コードフェンス” (---)内へ移動してください。注意: 条件付きレンダリング用のJavaScriptは、AstroではHTMLテンプレート内に直接書くことが多いです。

  4. Astro.props (EN)を使用して、以前にGatsby関数に渡された追加のpropsを参照してください。

  5. インポート済みコンポーネントをAstroに変換するか検討してください。公式Reactインテグレーションを使えばAstroファイル内で既存Reactコンポーネントを利用できますが、インタラクティブ性が不要なら.astroへ変換して軽量化できます。

  6. GraphQLクエリは削除し、importimport.meta.glob()でローカルファイルを読み込ます。

Gatsby Blogスターターを段階的に変換した例も参照してください。

以下のGatsbyコンポーネントと対応するAstroコンポーネントを比較してください:

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

レイアウトファイルをAstroレイアウトコンポーネントに変換するには、Gatsbyのレイアウトやテンプレートから始めてみてください。

Astroの各ページには必ず <html><head><body> タグが必要なため、複数ページで同じレイアウトファイルを再利用するのが一般的です。Astroではページコンテンツ差し込みに Reactの {children} ではなく <slot /> を使用し、import文も不要です。Gatsbyのlayout.jsやテンプレートにはこれらが含まれていません。

標準的なHTMLテンプレートと<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>
<!-- 既存のレイアウトテンプレートで`<slot />`要素を囲んでください。-->
<slot />
</body>
</html>
">

追加でサイトメタデータを含めたい場合は、Gatsbyのsrc/components/seo.jsのコードを再利用できます。注意: Astroでは<Helmet><Header>を使わずに<head>を直接記述します。ページコンテンツを分離して整理するには、コンポーネントを<head>内でインポートして使用することができます。

Gatsbyでは ページや投稿src/pages/内、またはcontentなどsrcの外に置かれている場合があります。Astroでは コンテンツコレクション を使わない限り、すべてのページコンテンツをsrc/内に配置する必要があります。

既存のGatsby JSX(.js)ページはJSXファイルから.astroページへ変換する必要があります。AstroではJSXページファイルをそのまま使用できません。

変換した.astroページsrc/pages/に置き、ファイルパスに基づいてページルートが自動生成されます。

AstroはMarkdownをネイティブサポートし、MDX用のオプション統合も提供しています。既存のMarkdownとMDXファイルを再利用できますが、フロントマターにAstro専用のlayoutプロパティを追加するなどの調整が必要な場合があります。これらのファイルもsrc/pages/に置けば自動的にファイルベースルーティングを利用できます。

あるいはAstroのコンテンツコレクションを使ってコンテンツを管理し、自分で取得して動的にページを生成することもできます。

Astroは生のHTMLを出力するため、ビルド後の出力を使用したE2Eテストができます。旧Gatsbyサイトのマークアップが再現できれば、既存のエンドツーエンドテストがそのまま動作する場合があります。JestやReact Testing LibraryなどをインポートしてReactコンポーネントをテストできます。

詳しくはテストガイドを参照してください。

Gatsbyにはルーティングやメタデータを含むトップレベル設定ファイルが複数あり、ルーティングに使用されます。Astroではこれらのgatsby-*.jsファイルを使用しませんが、内容を再利用できる場合があります。

  • gatsby-config.js: src/data/siteMetadata.js(またはsiteMetadata.json)にsiteMetadata: {}を移動して、ページレイアウトにサイト(タイトル、説明、ソーシャルアカウントなど)に関するデータをインポートします。

  • gatsby-browser.js: ここで使用されているものは、主要レイアウト<head>タグに直接追加することを考慮してください。

  • gatsby-node.js: Astroでは独自のノードを作成する必要はありませんが、このファイルのスキーマを確認して、Astroプロジェクトで型を定義するのに役立つかもしれません。

  • gatsby-ssr.js: AstroでSSRを使用する場合、astro.config.mjsに直接SSRアダプターを追加して構成してください。

以下はGatsby特有の構文をAstroに変換するいくつかの例です。Astroコンポーネントの書き方におけるAstroとJSXの違いも参照してください。

Gatsbyの<Link to=""><NavLink>などのコンポーネントをHTMLの<a href="">タグに変換します。

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

Astroにはリンク専用のコンポーネントはありませんが、独自の<Link>コンポーネントを作ってもかまいません。<Link>を他のコンポーネントのようにインポートして使用することができます。

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

必要に応じて、ファイルのインポートを相対ファイルパスで正確に参照するように変更します。これにはインポートエイリアスを使用したり、相対パスを完全に書くこともできます。

注意: .astroなど一部のファイルは拡張子を省略できません。

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

Gatsbyの{children}をAstroの<slot />に変換します。Astroは{children}を関数プロップとして受け取る必要なく、子要素を<slot />で自動的にレンダリングします。

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

Reactコンポーネントが複数の子要素を渡す場合は、named slotsを使用してAstroコンポーネントに移行できます。

特定の<slot />の使用方法に関する詳しい説明は特定の<slot />の使用方法を参照してください。

必要に応じて、CSS-in-JSライブラリ(例:styled-components)をAstroで使用できるCSSオプションに置き換える必要があります。

必要なら、インラインスタイルオブジェクト(style={{ fontWeight: "bold" }})をインラインHTMLスタイル属性(style="font-weight:bold;")に変換するか、Astroの<style>タグを使用してスコープCSSスタイルを記述します。

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

TailwindはTailwind Viteプラグインをインストールすればサポートされます。既存のTailwindコードは変更する必要はありません。

Gatsbyではgatsby-browser.jsでCSSインポートを使用してグローバルスタイリングを適用します。Astroでは、主なレイアウトコンポーネントに.cssファイルを直接インポートしてグローバルスタイリングを適用します。

詳しくはStyling in Astroを参照してください。

Gatsbyの<StaticImage /><GatsbyImage />コンポーネントをAstroの独自の画像統合コンポーネントに変換するか、または適切なReactコンポーネントで標準HTMLの<img>/JSXの<img />タグへ変換します。

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

Astroの<Image />コンポーネントは.astro.mdxファイルのみで動作します。完全なコンポーネント属性のリスト (EN)を確認し、いくつかはGatsbyの属性と異なります。

Markdownファイル(.md)で画像を使用を続ける場合は、標準のMarkdown構文(![]())を使用することができます。HTMLの<img>タグを直接使用することは、ローカル画像の.mdファイルではサポートされていません。そのため、それをMarkdown構文に変換する必要があります。

src/pages/post-1.md
# Markdown ページ
<!-- src/assets/stars.png をローカル画像として保存 -->
![A starry night sky.](../assets/stars.png)

Reactコンポーネント(.jsx)で画像を使用する場合は、標準のJSX画像構文(<img />)を使用することができます。Astroはこれらの画像を最適化しませんが、NPMパッケージをインストールして使用することでより柔軟な選択肢を提供できます。

詳しくはAstroの画像ガイドを参照してください。

GraphQLクエリへの参照をすべて削除し、代わりにローカルファイルのデータにアクセスするにはimport.meta.glob()を使用してください。

あるいは、コンテンツコレクションを使用している場合は、MarkdownやMDXファイルをgetEntry()およびgetCollection()でクエリしてください。

これらのデータリクエストは、Astroコンポーネントのフロントマター内で行われます。

src/pages/index.astro
---
import { getCollection } from 'astro:content';
// `src/content/blog/` エントリを全て取得する
const allBlogPosts = await getCollection('blog');
// `src/pages/posts/` エントリを全て取得する
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
}
}
}
}
`

ガイド付き例:GatsbyレイアウトをAstroへ変換する

セクションタイトル: ガイド付き例:GatsbyレイアウトをAstroへ変換する

この例では、Gatsbyのブログスターターやlayout.jssrc/layouts/Layout.astroに変換します。

ホームページでは1つ目のヘッダーを表示し、それ以外のページでは「Home」へのリンク付きヘッダーを表示します。

  1. return()のJSXを特定する

    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. Layout.astroを作成して、このreturn値をAstro構文に変換します。

    注意点:

    • {new Date().getFullYear()}はそのまま動作 🎉
    • {children}<slot />に変換 🦥
    • classNameclassに変換 📛
    • GatsbyAstroに変換 🚀
    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. レイアウトが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>
    ">
  • 必要なインポート、props、JavaScriptを追加します

    Astroでページルートとタイトルに基づいてヘッダーを条件付きでレンダリングするには:

    • Astro.props経由でpropsを提供します。(注:Astroのテンプレートでは、関数に渡すのではなく、フロントマターからpropsにアクセスします)
    • 三項演算子を使用して、ホームページの場合は1つの見出し、それ以外の場合は別の見出しを表示します
    • {header}{isRootPath}の変数は不要になったため削除します
    • Gatsbyの<Link/>タグを<a>アンカータグに置き換えます
    • classNameの代わりにclassを使用します
    • クラス名を有効にするために、プロジェクトからローカルのスタイルシートをインポートします
    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>
    ">
  • index.astroを更新して、この新しいレイアウトを使用して、必要なtitlepathname propsを渡します:

    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>
  • 条件付きヘッダーをテストするには、同じパターンを使用して2番目のページ、about.astroを作成します:

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

    Aboutページでは「Home」へのリンクが表示され、ホームページでは表示されません。

  • :::注意[共有したいリソースはありますか?] GatsbyサイトをAstroに移行する方法について、参考になる動画やブログ記事を見つけた(または作成した)場合は、このリストに追加してください! :::

    その他のマイグレーションガイド

    貢献する コミュニティ スポンサー
    OSZAR »