Open23

Astro公式ドキュメント調査

kzk4043kzk4043

Astro.js導入にあたってドキュメントの再調査
現時点で最新版はv4.8.6

参考

kzk4043kzk4043
  • ⭕⭕:超重要
  • ⭕:必要
  • 🔺:すぐは関係ないかもだが見ておくとBetter
  • ❌:対象外
  • ✅:要確認
kzk4043kzk4043

このスクラップ書いたときと公式Docsの構成が大きく変わっている…どこかで更新、追記する

kzk4043kzk4043

公式日本語版があった

  • Documentation
  • 🔺 Showcase:実装サンプル
    • githubとかが載ってるわけではなさそうなので見た目だけ
  • 🔺 Resources
    • Themes:有償、無償のテンプレ集(フィルタ可)
    • Integrations:プラグイン集(フィルタ可)
      • Official integrationはこっちで、あとは誰でも追加できる感じの様子
    • Tutorials:Documentation配下Tutorialへのリンク
  • 🔺 Blog:公式ブログ
kzk4043kzk4043

Documentation日本語もあるしわかりやすい。
そもそも思想がシンプルだからというのもあるかもしれない。
Reactと完全に切り離せるのでよりシンプルだし、Next.jsのときみたいにこれってどっちの機能だっけ…みたいにならないのも個人的によい。

kzk4043kzk4043

Getting Started

🔺Installation

npm create astro@latest
npm run dev

公式テンプレ

Editor Setup

To get started, install the Astro VS Code Extension today.
See how to set up TypeScript in your Astro project.

🔺Upgrade Astro

npx @astrojs/upgrade

We strongly recommend upgrading to the current major version of Astro as soon as you are able. Both the code and the documentation for earlier versions is unsupported.

The Core team will provide extended maintenance for security fixes only for one previous major version.

1個前まで保証なので2個古くなったらEOL。
半年弱に1回くらいメジャーリリースされているので、1年弱でEOLが来る感じ。

kzk4043kzk4043

Core Concepts

⭕⭕Why Astro?

Astroは、ブログやマーケティング、eコマースなど、コンテンツ駆動のウェブサイトを作成するためのウェブフレームワークです。ー中略ー他のフレームワークと比較してJavaScriptのオーバーヘッドと複雑さを低減することで知られています。高速でSEOに優れたウェブサイトが必要なら、Astroが最適です。

features

  • アイランド: コンテンツ駆動のウェブサイトに最適化されたコンポーネントベースのウェブアーキテクチャ
  • 自由なUI: React、Preact、Svelte、Vue、Solid、Lit、HTMX、ウェブコンポーネントなどをサポート
  • サーバーファースト: 重いレンダリング処理をサイト訪問者のデバイスから取り除きます。
  • デフォルトでゼロJS: サイトの読み込みを遅くするクライアントサイドのJavaScriptを減らします。
  • カスタマイズ可能: TailwindやMDXなど、100以上のインテグレーションから選択できます。

設計原則

  • コンテンツ駆動:マーケティングサイト、出版サイト、Docs、ブログ、ポートフォリオ、LP、コミュニティサイト、EC=コンテンツを見てもらうもの
    • Next.jsが向いているもの:アプリ。ダッシュボード、受信トレイ、SNS、Todo、Figma/Ping...=コンテンツを操作するもの
  • サーバーファースト: MPA
  • デフォルトで高速
    • 私たちの目標は、Astroを使えば、遅いウェブサイトを作るのはほぼ不可能になることです。
  • 簡単に使える:.astroはhtmlのスーパーセット
    • すでに手元にあるコンポーネントを再利用したりできるようにもしてあります。React、Preact、Svelte、Vue、Solid、Lit、さらにはウェブコンポーネントまですべてサポート
    • 「複雑さへのオプトイン」
  • 開発者を重視

⭕⭕Astro Islands

「アイランド」アーキテクチャの基本的な考え方は驚くほどシンプルです。サーバーでHTMLページをレンダリングし、高度に動的な領域にはプレースホルダーやスロットを挿入しておきます。そしてクライアント上では、サーバーでレンダリングされたHTMLを再利用して、その領域に小さな自己完結型のウィジェットを「ハイドレーション」します。
— Jason Miller、Preactの作者

アイランドアーキテクチャパターンがベースとしている技術は、パーシャル(partial)ハイドレーションや選択的(selective)ハイドレーションとしても知られる

対照的に、JavaScriptベースのウェブフレームワークの多くは、1つの大きなJavaScriptアプリケーション(シングルページアプリケーション、SPAとも呼ばれます)として、ウェブサイト全体をハイドレーションしてレンダリングします。SPAはシンプルでパワフルですが、クライアントサイドのJavaScriptが増えるため、ページロードパフォーマンスの問題に悩まされることになります。

SPAはjs増えがちでパフォーマンスに影響でることも。

各アイランドは常にページ上の他のアイランドから独立して動作します。ページ上に複数のアイランドを存在させることもできます。またアイランドは、それぞれ異なるコンポーネントコンテキストで実行されているにもかかわらず、状態を共有したり、互いに通信することが可能です。

islandは互いに独立しているが、状態の共有も可能。

デフォルトでは、AstroはすべてのUIコンポーネントをHTMLとCSSのみへと自動的にレンダリングし、クライアントサイドのJavaScriptを自動的に取り除きます。
静的なUIコンポーネントをインタラクティブなアイランドに変換するには、client:*ディレクティブを追加します。

かつロードタイミングを指示できるので、最適化しやすい。

Astroアイランドを使用するもっとも明白な利点は、パフォーマンス
大部分は高速で静的なHTMLに変換され、JavaScriptは、それを必要とする個々のコンポーネントにのみ読み込
もう1つのメリットは、並列ロードです。上のイラストの例では、優先度の低い「画像カルーセル」のアイランドが、優先度の高い「ヘッダー」のアイランドをブロックすることはありません。両者は並行してロードされ、独立してハイドレーションされます。つまり、ヘッダーは、ページ下部の重いカルーセルを待つことなく、すぐにインタラクティブな状態になります。

  • islandのメリット
    • パフォーマンス
    • 並列ロード/ハイドレーション(タイミング指示可能)
kzk4043kzk4043

チュートリアル

⭕⭕初めてのAstroブログ

やってもらう

🔺Tutorial - Extend with Content Collections

基本>コンテンツコレクションのチュートリアルと思われる。
推し機能ってこと?

🔺Tutorial - Extend with View Transitions

基本>ビュートランジションのチュートリアルと思われる。
推し機能ってこと?

kzk4043kzk4043

基本

⭕ディレクトリ構成

Next.jsと基本的には変わらなそう。

静的なpublic/ディレクトリとは違い、src/内にあるファイルはAstroによってビルドされ、処理されます。
Astroが予約しているディレクトリはsrc/pages/とsrc/content/だけです。その他のディレクトリは、自分にとって最適な方法で、自由に名前を変更したり再編成しても構いません。

⭕⭕コンポーネント

Astroコンポーネントについて知っておくべきもっとも重要なことは、クライアント上でレンダリングされないということ
フロントマターの内部にJavaScriptコードを含められますが、それらはすべて、ユーザーのブラウザに送られる最終的なページからは取り除かれます。

---
// フロントマター(MDX用語…?)
// コンポーネントスクリプト (JavaScript)→正式用語はどれだ…?
// ここの処理はクラアントにそもそも送信されず、実行できない
---"---"はコードフェンスと言うらしい)
<!-- コンポーネントテンプレート (HTML + JS Expressions) -->
<!-- スクリプトタグを埋め込めばクライアントで実行できる(はず。✅試す) -->

.astroコンポは基本的にはサーバサイド用だと思うほうがよさそう。クライアントでゴニョゴニョしたいなら最初から.tsx等で作る。
.astroで作って、cdnとかで読み込んでとかも考えられなくはないが…比較した方がいいかも?

フロントマターでの処理

  • 他のAstroコンポーネントのインポート
  • 他のフレームワークコンポーネント(Reactなど)のインポート
  • データ(JSONファイルなど)のインポート
  • APIやデータベースからコンテンツを取得するコード
  • テンプレートで参照する変数の作成

✅Astroで用意されているものの確認(Astro.propsとか)

コンポーネントテンプレートで書けるもの

  • JavaScriptの式
  • Astroの<style>と<script>タグ
  • インポートしたコンポーネント
  • 特別なAstroディレクティブもサポート

✅テンプレートディレクティブ(<p class:list={["add", "dynamic", {classNames: true}]} />
clsx不要か。

props

Astro.propsで定義。
✅型はinterfaceのみ?

slot === children

ここはVueっぽい感じ。名前付きSlotあり。

// 子側(`src/components/Wrapper.astro`)
<div id="content-wrapper">
  <Header />
  <slot name="after-header" />  <!--  `slot="after-header"` 属性を持つ子要素はここに入ります。 -->
  <Logo />
  <h1>{title}</h1>
  <slot />  <!--  `slot`属性をもたない子要素、`slot="default"`属性を持つ子要素はここに入ります。 -->
  <Footer />
  <slot name="after-footer" />  <!--  `slot="after-footer"` 属性を持つ子要素はここに入ります。 -->
</div>

// 親側(src/pages/fred.astro)
---
import Wrapper from '../components/Wrapper.astro';
---
<Wrapper title="フレッドのページ">
  <img src="https://my.photo/fred.jpg" slot="after-header" />
  <h2>フレッドについて</h2>
  <p>ここでは、フレッドについて紹介します。</p>
  <p slot="after-footer">Copyright 2022</p>
</Wrapper>

<div>でラップせずに複数のHTML要素をコンポーネントの<slot/>プレースホルダーに渡すには、Astroの<Fragment/>コンポーネントのslot=""属性を使用します。
Astroのスロット名は、map関数の中などで動的には生成できません。UIフレームワークコンポーネントの内部でこの機能が必要な場合は、フレームワーク側で動的なスロットを生成しておくのがベストです。

受け渡しちょっとレビュする時むずそう…✅ちゃんと理解した方がいいかも
フォールバック(デフォルトのslot)の設定可

⭕⭕ページ

  • .astro
  • .md
  • .mdx (MDXインテグレーションがインストールされている場合)
  • .html
  • [.js/.ts] (エンドポイント=APIルートなどとして)

カスタムの404エラーページを作成するには、src/pagesに404.astroまたは404.mdファイルを作成します。

⭕レイアウト

md/mdxを使う際は再読。

⭕⭕Astroテンプレートの構文

HTML属性は文字列に変換されるため、関数やオブジェクトをHTML要素に渡すことはできません。たとえば、Astroコンポーネント内のHTML要素にイベントハンドラを割り当てることはできません。

→代わりにscriptタグを使う

動的タグ

動的タグを使用する場合は、以下の点に注意してください。
変数名は大文字で始める必要があります。 たとえば、elementではなくElementを使用します。そうしないと、Astroは変数名をそのままHTMLタグとしてレンダリングしようとします。
ハイドレーションディレクティブは使えません。client:*ハイドレーションディレクティブを使用する場合、Astroはバンドルする対象のコンポーネントを知る必要がありますが、動的タグパターンではこれが機能しなくなるためです。

Astro構文とJSXの違い

  • 属性はHTMLと同等
- <div className="box" dataValue="3" />
+ <div class="box" data-value="3" />
  • 単一の要素で囲う必要はない
  • HTML/jsスタイルのコメントが使用可

HTMLスタイルのコメントはブラウザのDOMに含まれますが、JSのコメントはスキップされます。

これは結構大事かもしれん

⭕レンダリングモード

  • ビルド時の事前レンダリングとオンデマンドレンダリング両方可。
  • それにアイランドによるCSRを混ぜられる。
  • アニメーションやルート間のナビゲーションをまたいだ状態の保持のためにミドルウェアやAstroのビュートランジションAPIを使えば、高度にインタラクティブなアプリも作成できます。

モード

  • デフォルトのレンダリングモードは output: 'static' です。これはビルド時にすべてのページルートのHTMLを作成します。
  • output: 'server' は、多くのルートがオンデマンドであるような、高度に動的なサイトに適しています。
  • output: 'hybrid' は、一部のルートがオンデマンドであるような、ほぼ静的なサイトに適しています。

✅ output: 'hybrid'でよい?server/hybridの違いがわからないので比較する

kzk4043kzk4043

ディレクティブ

.astroコンポ内(と、一部の.mdx)だけで使える特別なHTML attributeで、生成されるHTMLからは当然除外されている。
コンパイラに見えない書き方(<X {...attr}>)をすれば動作しない→✅これはちょっと確認必要か?

class:list

内部的にclsx使ってるっぽい。ので、使用感は同等のはず。

set:html

=el.innerHTML/dangerouselySetInnerHTML

The value is not automatically escaped by Astro! Be sure that you trust the value, or that you have escaped it manually before passing it to the template.

注意。ユーザ可変変数を入れないか、入れるならサニタイズする。

set:textもあるが、<div set:text={someText}><div>{someText}</div>は同等らしいので使わない。

client directives

Hydration directives are not supported when using dynamic tags and custom components passed via the components prop.

hydration directiveってclient directiveのこと?

  • なしなら、jsなしでのレンダリング
  • client:load(初期ロード時)
  • client:idle(初期ロード終わったあと)
  • client:visible(IntersectionObserverが内部で使われている)
    • client:visible={{rootMargin}}
  • client:media(指定したCSS media queryにマッチした場合とのことだがタイミングがちょっと不明)
  • client:only(サーバでレンダリングしない。UIライブラリを指定する必要あり。)
  • カスタムもできるらしいが一旦十分そう

<script>/<style>限定のディレクティブ

is:global

css をscopedからglobalにできるらしいが、globalはファイル切り出すはずだからたぶん使わない。

is:inline

Astroによってバンドルされなくなり、

Will not be bundled into an external file. This means that attributes like defer which control the loading of an external file will have no effect.
Will not be deduplicated—the element will appear as many times as it is rendered.
Will not have its import/@import/url() references resolved relative to the .astro file.
Will be rendered in the final output HTML exactly where it is authored.
Styles will be global and not scoped to the component.

The is:inline directive is implied whenever any attribute other than src is used on a <script> or <style> tag.

これはどういう…?src以外のタグ使ったらAstroでは扱えないからis:inline扱いするよってこと?

define:vars

フロントマターの処理結果をクライアントで使いたい時に、属性値として仕込む感じ。→かと思ったら他に渡す方法があるみたい。どういうこと。→ガイド>スクリプトとイベントハンドリング

Using define:vars on a <script> tag implies the is:inline directive, which means your scripts won’t be bundled and will be inlined directly into the HTML.

やっぱsrc以外使ったらis:inline扱いするってことっぽいな。

is:raw

対象タグのchildrenをテキストとして扱う

kzk4043kzk4043

組み込み機能

🔺コンテンツコレクション

コレクションとは…?
contentをパスとして使えないってこと…?地味にリスクでは…?→違う、src/contentフォルダか
解説記事によると同じようなページのFrontmatterの型付け用?
✅使う場面の確認

  • ローカルの記事データなどへのアクセスの仕方をいい感じにするもの。型付けとか

🔺ビュートランジション

たぶん対象外だが完全に対象外と確定できるわけではないか…

⭕プリフェッチ

✅結構細かく設定できそうだが、一律でルール決めた方がよさそう

astro.config.mjs
// すべてのリンクをデフォルトでプリフェッチする
import { defineConfig } from 'astro/config';

export default defineConfig({
  prefetch: {
    prefetchAll: true
  }
});
  • インフラ費用に跳ねる
    • viewportはちょっと危険かもしれない?tapとか?
  • next/linkはviewport
    • 何を取ってきてる…?

⭕開発ツールバー

devビルドでToolbarが出る様子。
disableできるとのことだが、特に害はなさそう。

kzk4043kzk4043

インテグレーション

⭕インテグレーションの追加

インテグレーションは基本astro addで追加。
インテグレーションと普通のNPMパッケージは何が違うんだろうか。

⭕⭕UIフレームワーク

UIフレームワークコンポーネントで利用可能なハイドレーションのディレクティブ

  • client:load
  • client:idle
  • client:visible
  • client:media={QUERY}
  • client:only={FRAMEWORK}

Astro コンポーネントはクライアントサイドのランタイムを持たないHTMLのみを表示するコンポーネントです。しかし、<script>タグをAstroコンポーネントのテンプレートの中で使い、グローバルスコープで実行するJavaScriptをブラウザに送信することはできます。

フレームワークコンポーネントの中でAstroコンポーネントを使用できますか?

astroコンポ内ではどんなUIコンポもインポートできるが、逆に各UIコンポ内でastroコンポはインポートできない。ただし、astroコンポ内で各UIコンポのslotとしてAstroコンポを渡すことは可能。

Astroコンポーネントをハイドレーションすることはできますか?

client:という修飾子を使ってAstroコンポーネントをハイドレーションしようとするとエラーになるはずです。
Astro コンポーネントはクライアントサイドのランタイムを持たないHTMLのみを表示するコンポーネントです。しかし、<script>タグをAstroコンポーネントのテンプレートの中で使い、グローバルスコープで実行するJavaScriptをブラウザに送信することはできます。

⭕SSRアダプター

見る前の疑問

  • アダプタはなんにせよ追加が必要?→staticなら不要
  • そもそもデフォルトはオンデマンドレンダリングじゃないの…?→デフォルトstatic
  • hybrid/server以外は何がある…?→static
  • アダプタ入れないと何になる?→static

✅アダプタ入れた場合にGTM的に大丈夫か

以下が必要な場合に検討

  • APIエンドポイントとして使う場合
  • ページのアクセス制御が必要な場合
  • 頻繁に変更されるコンテンツ

Astroは、Node.js、Vercel、Netlify、Cloudflareの公式アダプターを提供しています。
Astroのオンデマンドレンダリングの出力モード(serverとhybrid)はいずれも、可能な限り個々のルートを事前レンダリングすることで、静的サイトのパフォーマンスを活かせるようにします。

だったら2つの違いは…?

  • server
    • 事前レンダリングにオプトイン=export const prerender = trueをページに追加
  • hybrid
    • 事前レンダリングをオプトアウト=export const prerender = falseをページに追加

オンデマンドレンダリングの機能

HTML streaming

HTMLストリーミングにより、ドキュメントはチャンクへと分割され、ネットワークを経由して順に送信され、その順番でページにレンダリングされます。serverまたはhybridモードでは、Astroはコンポーネントをレンダリングする際にブラウザに送信するためにHTMLストリーミングを使用します。これによりユーザーにできるだけ早くHTMLを表示できますが、ネットワークの状況によっては、大きなドキュメントのダウンロードが遅れたり、データの取得を待つことでページのレンダリングがブロックされることがあります。

cookie(Astro.cookies)

Request

Response

  return new Response(null, {
    status: 404,
    statusText: 'Not found'
  });

❌Astro DB

kzk4043kzk4043

SSRアダプタ(Node)

pnpm astro add node

mode

  • middleware
    • middleware mode allows the built output to be used as middleware for another Node.js server, like Express.js or Fastify.
    • 処理はExpressとかに渡すけどそのmiddlewareとして動く的な?
  • standalone
    • 普通はこっちか…?

この辺が自分が想像するSSRの設定ぽい(astro add nodeしたらデフォルトでこれになってた)

kzk4043kzk4043

レシピ

⭕⭕Astroへの移行

プロジェクトの設計はどう変わりますか?

  • 不要なJavaScriptをブラウザに送信しないための、Astroアイランドによる設計。
  • クライアントサイドの<script>タグやUIフレームワークコンポーネントを使用した、クライアントサイドでのインタラクティビティの提供。
  • アプリケーション全体にまたがるフックやラッパーではなく、Nano Storesやローカルストレージによる共有状態の管理。

Next.jsからの移行

Next/Astro共通点

  • The syntax of .astro files is similar to JSX. Writing Astro should feel familiar.
  • Astro projects can also be SSG or SSR with page-level prerendering.
  • Astro uses file-based routing, and allows specially named pages to create dynamic routes.
  • Astro is component-based, and your markup structure will be similar before and after your migration.
  • Astro has official integrations for React, Preact, and Solid so you can use your existing JSX components. Note that in Astro, these files must have a .jsx or .tsx extension.
  • Astro has support for installing NPM packages, including React libraries. Many of your existing dependencies will work in Astro.
  • public/src/pagesの役割

Next/Astro key diff

  • SPA/MPA
  • ページテンプレートを関数として返すのではなく、コードフェンスでjsとHTMLを分離
  • コンテンツドリブン

移行

  • Nextのpages/_document.jsxはlayoutとかに普通に入れればよい。
  • Nextのsrc/pages配下のルーティング用jsxファイルはastroファイルにしなければならない
  • Nextの<Link to="">コンポは普通のaタグに
  • importはファイル拡張子まで必要そう
  • Nextの{children}<slot />
  • top-level await
  • tailwindはサポートされてるが、css in jsは無理っぽい?
  • Nextの<Image />コンポはReactコンポ内では普通のimgタグに
    • Astroの<Image />はastroファイルでのみ使用可
  • astroファイルではイテレーション時にkeyは不要

❌Astro Studioとの接続

❌CMSとの接続

CMSなし。CMSめちゃめちゃあるんやな。

❌バックエンドサービスの追加

なし

🔺サイトのデプロイ

その他のレシピ

✅いりそうなやつ確認

  • ❌RSSフィードの追加
    • AstroサイトにRSSフィードを追加して、ユーザーがコンテンツを購読できるようにします。
  • ViteまたはRollupプラグインをインストールする
    • プロジェクトにRollupプラグインを追加することでYAMLデータをインポートする方法を学びます。
  • Build a custom image component
    • Learn how to build a custom image component that supports media queries using the getImage function.
  • Build forms with API routes
    • Learn how to use JavaScript to send form submissions to an API Route.
  • Build HTML forms in Astro pages
    • Learn how to build HTML forms and handle submissions in your frontmatter.
  • ❌AstroでBunを使う
    • AstroサイトでのBunの使い方を紹介します。
  • Call endpoints from the server
    • Learn how to call endpoints from the server in Astro.
  • Captcha(キャプチャ)の検証
    • APIルートを作成し、クライアントから取得する方法を学びます。
  • ⭕DockerでAstroサイトを構築する
    • Dockerを使ってAstroサイトを構築する方法を紹介します。
  • Dynamically import images
    • Learn how to dynamically import images using Vite's import.meta.glob function.
  • Add icons to external links
    • Learn how to install a rehype plugin to add icons to external links in your Markdown files.
  • ❌Add i18n features
    • Use dynamic routing and content collections to add internationalization support to your Astro site.
  • Create a dev toolbar app
    • Learn how to create a dev toolbar app for your site.
  • Add last modified time
    • Build a remark plugin to add the last modified time to your Markdown and MDX.
  • Add reading time
    • Build a remark plugin to add reading time to your Markdown or MDX files.
  • ⭕Share state between Islands
    • Learn how to share state across framework components with Nano Stores.
  • ⭕Share state between Astro Components
    • Learn how to share state across Astro components with Nano Stores.
  • ⭕Using streaming to improve page performance
    • Learn how to use streaming to improve page performance.
  • ❌Style rendered Markdown with Tailwind Typography
    • Learn how to use @tailwind/typography to style your rendered Markdown.
kzk4043kzk4043

ガイド

⭕⭕ルーティング

ルート間の移動に標準的なHTMLの<a>要素を使用します。フレームワーク固有の<Link>コンポーネントは提供されていません。

<p>Astroの<a href="/about/">概要</a>についてもっと読む!</p>
  • ファイルベースルーティング
    • 静的
      • .astro/md/mdxはファイルパスがそのまま
    • 動的
      • [path]形式 ex) src/pages/authors/[author].astro
        • 複数も行ける ex) src/pages/[lang]-[version]/info.astro
        • レストパラメータ ex) src/pages/sequences/[...path].astro
          • {params: {path: 'one/two/three'}}
          • {params: {path: 'four'}},
          • {params: {path: undefined }}
      • モード
        • SSGモード
        • サーバ(SSR)モード

SSGモード→多分使わない

---
// getStaticPathsで予めパスを決めておいて、事前ビルド
export function getStaticPaths() {
  return [
    {params: {dog: 'clifford'}},
    {params: {dog: 'rover'}},
    {params: {dog: 'spot'}},
  ];
}

const { dog } = Astro.params;
---
<div>いい子だ、{dog}</div>

サーバ(SSR)モード

事前ビルドされない。「静的」ルートではないため、getStaticPathsは使用できない。
特に設定とかはなさそう?で、getStaticPathsがなければSSRモードなのかな。

❌Markdown

⭕スクリプトとイベントハンドリング

基本的にクライアントサイドで動くコンポはReactで作るのでいらないと思われるが、必要になる可能性もある。

Astroは<script>タグを処理してバンドルし、npmモジュールのインポートやTypeScriptの記述などをサポートします。

ただのscriptタグとは違うっぽい。

  • すべてのインポートはバンドルされ、ローカルファイルやNodeモジュールをインポートできます。
  • 処理されたスクリプトは、type="module"としてページの<head>に挿入されます。
    • パフォーマンスメリット
      • レンダリングがブロックされません。モジュールスクリプトとその依存関係がロードされる間、ブラウザは残りのHTMLの処理を続けます。
      • ブラウザはモジュールスクリプトを実行する前に、HTMLが処理されるのを待ちます。“load”イベントをリッスンする必要はありません。
      • asyncとdefer属性は不要です。モジュールスクリプトは常に延期されます。→逆にasync入れるとページが完全に読み込まれる前にモジュールスクリプトが実行されます、とのこと
  • TypeScriptを対応しており、TypeScriptファイルもインポートできます
  • コンポーネントがページに複数回使われている場合、スクリプトは一度だけ含まれます。

is:inlineにすればAstro処理対象外になる

  • 書かれたとおりにレンダリングされます。
  • ローカルインポートが解決されずに動作しません。
  • コンポーネント内の場合、コンポーネントが利用されている箇所全てに繰り返しレンダリングされます。

スクリプトのインポート

<!-- このローカルのTypeScriptファイルも動作します。 -->
<script src="./script-with-types.ts"></script>

// プロジェクトのsrcフォルダ以外のスクリプトをロードするには、is:inlineディレクティブを含めます。
<!-- `public/my-script.js`スクリプトへの絶対パス -->
<script is:inline src="/my-script.js"></script>

<!-- リモートサーバー上にあるスクリプトへの完全なURL -->
<script is:inline src="https://my-analytics.com/script.js"></script>

カスタム要素を使ってコンポ作成

<astro-heart>
  <button aria-label="Heart">💜</button> × <span>0</span>
</astro-heart>

<astro-heart>のようなカスタム要素を作り、それにHTML要素の動作を定義したクラスをdefineする。素のHTML/jsな感じ。たぶん使わない。

フロントマター変数をスクリプトに渡す

フロントマターでの値をクライアント側で参照するには、<astro-greet data-message={message}>のようにdata-xxxに埋め込み、const message = this.dataset.message;のようにthis.dataset.xxxでアクセスする。

✅directivesのdefine:varsと結局何が違う…?

⭕CSSとスタイル

Astroコンポ

  • Tailwind/Sass/Less使用可
  • <style>での記述はデフォルトでscoped
    • <style is:global>でグローバル化できるが、グローバルスタイルは別で切り出す
    • :global()で子要素にスタイルを当てられるが、基本やらない
  • define:varsでフロントマターの変数を渡せる
// これらは同じです
<p style={{ color: "brown", textDecoration: "underline" }}>テキスト</p>
<p style="color: brown; text-decoration: underline;">テキスト</p>

インポート

---
// ローカルスタイルシートのインポート
// AstroはこのCSSを自動的にバンドルし、最適化します。
// これは.scssや.stylなどのプリプロセッサーのファイルにも有効です。
import '../styles/utils.css';
// npmパッケージからスタイルシートをインポート
import 'package-name/styles.css';
---
<html>
    <head>
      <!--  ローカル: /public/styles/global.css(publicなので最適化処理等はなし。必要ならimportする。) -->
      <link rel="stylesheet" href="/styles/global.css" />
      <!-- 外部  -->
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.24.1/themes/prism-tomorrow.css">
    </head>
    <!-- ページの内容 -->
</html>

Astro CSSのルールは、つぎの出現順で評価されます。

  1. head内の<link>タグ (最も低い優先順位)
  2. インポートされたスタイル
  3. scoped styles (最優先)

Astroでよくあるパターンは、Layoutコンポーネントの中にグローバルCSSをインポートすることです。Layoutコンポーネントは必ず他のインポートより先にインポートして、優先順位を一番低くしてください。

Astroはデフォルトでは、HTML内の4kB以上のスタイルシートのみを<link rel="stylesheet">タグとしてリンクし、それ以外のものは<style type="text/css">にインライン化

Reactコンポ

  • Reactコンポの仕様に従う

⭕⭕画像

ローカル画像は、Astroが変換、最適化、バンドルできるように、可能な限りsrc/に保存することをおすすめします

最適化処理内容次第ではpublicに入れない?

<Image /> (astro:assets)

  • <Image /> (astro:assets)
    • 最適化される
      • src内画像
      • 設定済みリモート画像→width/height必須
    • されない(使用はできる)
      • publicフォルダ内→width/height必須
      • 設定されていないリモート画像→width/height必須

<Image />コンポーネントは、ローカル画像の正しいwidthとheightを自動的に設定することで、CLSへと最適化します。
ローカル画像をオリジナルのアスペクト比で使用する場合、widthとheightはソースファイルから自動的に推測されるため、必須ではありません。

どうやって…?ちょい不安だな。→オリジナルで使わない場合は注意?
sharpってやつで処理してる?

densities/widths(+sizes)

srcset生成用のastroプロパティ(この辺の話)。どちらかの値を使用する(両方は書けない)。

  • densities = 生成する画像のピクセル密度の配列です。
  • widths(+sizes) = 生成する画像の幅の配列

<Picture />

pictureタグを最適化された形で使えるぽい。img/pictureの違いよくわかってない→参考1 参考2→picture使う場面ある…?

⭕フォント

⭕インポート

デフォルトでサポートしている形式

  • Astroコンポーネント(.astro)
  • Markdown(.md, .markdownなど)
  • JavaScript(.js、.mjs)/TypeScript(.ts、.tsx)
  • NPMパッケージ
  • JSON(.json)
  • JSX(.jsx、.tsx)
  • CSS(.css)/CSS Modules(.module.css)
  • イメージとアセット(.svg、.jpg、.pngなど)

Astroは、ESMを使います

TypeScriptのモジュール解決ルールでは、TypeScriptファイルをインポートする際に.tsと.tsxのファイル拡張子を使用するべきではありません。代わりに、.js/.jsxというファイル拡張子を使うか、ファイル拡張子を完全に省略する必要があります。

え、なんでだっけ…

パッケージがレガシーフォーマットを使用して公開されていた場合、Astroはimport文が機能するように、パッケージをESMに変換します。場合によっては、動作させるためにvite configを調整する必要があるかもしれません。

Astro.glob()(コレクションの場合はgetCollection()

Astro.glob()は、多数のファイルを一度にインポートするための方法です。

---
// `./src/pages/post/`の`.md`で終わるすべてのファイルをインポート
const posts = await Astro.glob('../pages/post/*.md');
---
<!-- ブログ投稿の最初の5つの<article>をレンダリング -->
<div>
{posts.slice(0, 4).map((post) => (
  <article>
    <h2>{post.frontmatter.title}</h2>
    <p>{post.frontmatter.description}</p>
    <a href={post.url}>もっと読む</a>
  </article>
))}
</div>

Nodeビルトイン

Astroのユーザーには、可能な限りNode.jsのビルトイン(fs、pathなど)を避けることをおすすめします。
AstroはNode.jsのビルトインを、Nodeの新しいプレフィックスであるnode:を使ってサポートしています。

❌エンドポイント

APIルートの話?

⭕データフェッチ

  • top-level await
  • グローバルfetch関数あり

❌国際化

❌ミドルウェア

❌Eコマース

⭕テスト

  • Vitest
  • Cypress
  • Playwright

⭕認証

Astro向けの公式の認証ソリューションはありませんが、インテグレーションディレクトリではコミュニティの “auth” インテグレーションが検索できます。

  • Lucia
    • 初めて聞いたけどおすすめっぽい?
  • Auth.js
    • コミュニティのアダプタがある

⭕トラブルシューティング

  • Cannot use import statement outside a module (モジュール外でimport文が使えません)
  • Unable to render component(コンポーネントをレンダリングできません)
    • window/documentにアクセスするならclient:onlyにする…?か、分岐じゃだめなんかな?
  • Expected a default export(デフォルトのエクスポートを予想)
  • Astro.glob() - no matches found(一致するものはありません)
  • yarn 2+系と相性悪いのか
  • Astro <Debug />コンポを使うと、ブラウザで試しやすい?
kzk4043kzk4043

許可された画像ソース

セキュリティ用ってよりはastroファイルにおけるImageコンポで最適化するかどうか?

外部ソースを扱う際の保護を強化するために、設定で指定した許可された画像ソースからのリモート画像のみ処理されます。ただし、リモート画像の表示は常に可能です。

セキュリティ用にドメインを絞るとかっていう話じゃないっぽいな。

kzk4043kzk4043

Dynamically import images

src/フォルダーから動的に画像を読み込むには、

// これで画像データ取ってこれるっぽい?
const images = import.meta.glob<{ default: ImageMetadata }>('/src/assets/*.{jpeg,jpg,png,gif}');

// →imagesはこんな感じのデータになるっぽい。
// const images = {
//   './assets/avatar-1.jpg': () => import('./assets/avatar-1.jpg'),
//   './assets/avatar-2.png': () => import('./assets/avatar-2.png'),
//   './assets/avatar-3.jpeg': () => import('./assets/avatar-3.jpeg')
// }

// 実際の使い方。画像パスとして使える
<Image src={images[imagePath]()} alt={altText} />
kzk4043kzk4043

設定

⭕Astroの設定ファイル

プロジェクトにastro.config.mjsファイルを追加することで、Astroの動作をカスタマイズできます。
astro.config.js、astro.config.mjs、astro.config.cjs、astro.config.tsという複数のファイル形式をサポートしています。多くの場合は.mjsを、設定ファイルをTypeScriptで記述する場合は.tsを使用することをおすすめします。

全ての設定はここ

Astroは他のファイルをロードする前に設定ファイルを評価します。そのため、.envファイルによってセットされた環境変数を取得するためにimport.meta.envは使えません。
設定ファイルの中でprocess.envを使用して、CLIによりセットされたものなど、その他の環境変数の取得は可能です。
また、ViteのloadEnvヘルパーを使用して、.envファイルを手動でロードすることもできます。

⭕TypeScript

  • "verbatimModuleSyntax": trueがデフォルト
  • Importエイリアスをサポート
  • AstroコンポのPropsはinterface Props
interface Props {
  name: string;
  greeting?: string;
}

コンポーネントがデフォルトスロットから子要素を受け取る必要がある場合は、type Props = { children: any; };によりこれを強制できます。

え、any固定なん…?

  • 型ユーティリティ
    • 組み込みのHTML属性

⭕importエイリアス

⭕環境変数

kzk4043kzk4043

リファレンス

リファレンスなので、何かあった時に見る

設定方法

ランタイムAPI

インテグレーションAPI

アダプターAPI

画像サービスAPI

開発ツールバーアプリAPI

テンプレートディレクティブ

Astro CLI

エラーリファレンス

NPMパッケージの形式

kzk4043kzk4043

コミュニティリソース

ここも適宜参照。

🔺コース、ガイド、レシピ

公式ニュースレター登録した。

Astroの以前のバージョンに基づいている可能性があります。コミュニティのコンテンツを使用する際には、公開日を確認し、プロジェクトの要件に応じて適宜調整することをお勧めします。

パット見3.X用が多そう…?

🔺トーク、インタビュー、配信

眺めてみてもよさそう

kzk4043kzk4043

Client-Side Interactivity

新しくセクションが追加されていたので追記

フレームワークコンポーネント

以前のUIフレームワークのページと同等?→ほぼ同等で少し再構成したものだった

デフォルトでは、フレームワークのコンポーネントは静的なHTMLとしてレンダリングされます。これはインタラクティブでないコンポーネントをテンプレート化するのに便利で、必要のないJavaScriptをクライアントに送信するのを防ぎます。

インタラクティブなコンポーネント

client:onlyを除く全てのclientディレクティブで、コンポーネントはまず最初にサーバー上でレンダリングされて静的なHTMLを生成します。ーその後コンポーネントはハイドレートしインタラクティブになります。
ページ上の複数のコンポーネントが同じフレームワークを使用する場合、フレームワークは一度だけ送信されます。

フレームワークコンポーネントに関数をプロパティとして渡せますが、それはサーバーレンダリングの間だけ機能します。もしこの関数をハイドレードされたコンポーネント(例えば、イベントハンドラーとして)で使用しようとするとエラーが発生します。
これはAstroでは関数をシリアライズ(サーバーからクライアントへの転送)できないためです。

関数は渡せない。イベントハンドラとか。
子要素は渡せるが、HTMLとしてであり、例えばReactとしては渡せない。

UIフレームワークコンポーネント(例:.jsxや.svelte)の中で.astroコンポーネントをインポートすることはできません。
しかし、Astroの<slot />パターンを利用して、Astroコンポーネントが生成した静的コンテンツを .astroコンポーネントの中でフレームワークコンポーネントに子要素として渡すことはできます。

スクリプトとイベントハンドリング

⭕スクリプトとイベントハンドリングとほぼ同等