2026/1/22
Astroで画像を扱う
Astroで画像を扱う方法
Astro プログラミング
Astroで画像を
Images
Learn how to use images in Astro.
Astroには<Image>というコンポーネントが存在します。
これはAstroの画像最適化機能を使う場合に使用しますが、これを積極的に利用していこうという回。
Imageコンポーネントの利用方法
---import { Image } from "astro:assets"import gazou from "@/assets/gazou.png"---
...<Image src={gazou} alt="これは画像です。" />...みたいに使うことが出来ます。このサイトにはありませんが、ロゴなんかを表示するときに。
このサイトで使用されている箇所としては、
- カバー画像
- 記事内の画像
だけですね。ここしか無い。
デフォルト設定でwebpに変換されます。
カバー画像として扱う
このブログではフロントマターにcoverというプロパティが存在し、相対パスで指定することが出来ます。
import { defineCollection } from "astro:content";import { glob } from "astro/loaders";import { z } from "astro/zod";
const blog = defineCollection({ loader: glob({ pattern: '**/*.{md,mdx}', base: './contents/blog' }), schema: ({ image }) => z.object({ title: z.string(), description: z.string().optional(), pubDate: z.date(), tags: z.array(z.string()).optional(), draft: z.boolean().default(false), categorie: z.string().optional(), cover: image().optional() })})
export const collections = { blog };上のようになっています。schemaのところに({ image })とありますが、コレが重要です。
後は使用箇所で使用していくだけです。
---import Layout from "@/layouts/Layout.astro";import Toc from "@/components/Toc.astro";import { Image } from "astro:assets";import defaultCover from '@/assets/default.jpg';import { getCollection, render } from "astro:content";export async function getStaticPaths() { const posts = await getCollection("blog"); return posts.map(post => ({ params: { id: post.id }, props: { post } }));}
const { post } = Astro.props;const { Content, headings } = await render(post);---
<Layout> <section class="pt-16 h-screen min-h-screen"> <div class="container mx-auto w-full max-w-7xl flex flex-col px-6"> <div class="flex flex-col items-center justify-center text-center py-6"> <Image class="rounded-lg aspect-21/9 object-cover object-center mb-4" src={post.data.cover || defaultCover} alt={post.data.title} /> <h1 class="text-3xl font-bold">{post.data.title}</h1> <p class="text-gray-600 mt-2">{post.data.pubDate.toLocaleDateString('ja-jp')}</p> </div> <div class="grid grid-cols-1 md:grid-cols-3 gap-2 w-full py-8"> <div class="md:col-span-2 prose prose-base w-full"> <Content /> </div> <div class="sticky top-24 hidden md:block"> <Toc headings={headings} /> </div> </div> </div> </section></Layout>これは当サイトで使用しているコードです。<Image>のsrcに渡しています。
OGP画像として
OGP画像として渡す場合には一工夫(?)いります。
まずastro.config.mjsでサイトのURLを設定する必要があります。
import { defineConfig } from 'astro/config';
export default defineConfig({ site: 'https://ast.monukedayo.cc',});siteのところですね。
あとはURLを組み立てるだけです。私はLayout.astroで組み立てています。
---import type { ImageMetadata } from 'astro';import defaultCover from '@/assets/default.jpg';
interface meta { title: string, description?: string, image?: ImageMetadata}
interface Props { meta?: meta}
const ogImage = meta?.image ? new URL(meta.image.src, Astro.url).toString() : new URL(defaultCover.src, Astro.url).toString()---
<!doctype html><html lang="ja"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width" /> <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> {/* 他のプロパティ */} <meta property="og:image" content={ogImage} /> </head> <body> <slot /> </body></html>雑な気がしますが、動いてるのでヨシ!!
終わり
触りの部分だけですが、他の部分は詳しく書いている記事を参照していただくとして…(他力本願寺)
あまり深く考えなくてもパフォーマンスは高く保たれます。私はそういう考えで書いてます。
以上ッ!!!