AstroとWordpressでJamstack その4 Layoutを作る BaseHead(Metaの出力)
公開日時:2024-03-22T09:46:32.483Z
Layoutといっても実際の配置ではなくLayout.astroです。
LayoutはCompornentsを配置するファイルと言えます。
HTMLの構成的に
<html>
<head>
<title></title>
<meta>
</head>
<body>
<header></header>
<main>
<footer></footer>
</body>
</html>
を作成します。
ここで<head>〜〜</head>は繰り返し使うのでCompornent化します。
<header>〜〜</header>,<footer></footer>も同様です。
それぞれ
BaseHead.astro
Header.astro
Footer.astro
としてcompornentsディレクトリに作成します。
BaseHead.astroの作成
作成するコードは以下の通りです。
---
// global.cssを読み込む。
import '../styles/global.css';
//faviconはpublic直下に配置。
import favicon from '../../public/favicon.ico'
import defaultOgpImg from '../assets/img/defaultOGP.jpg'
//Canonical URLを astro.config.mjsのsiteから取得して生成
//const canonicalURL = new URL(Astro.url.pathname, Astro.site);
//propsで渡される値を定義する。xxx?でなしでもOK
interface Props {
title: string;
description: string;
image?: string;
pubDate?: string;
updateDate?: string;
}
//pubDate,updateDateが指定されないときように
const nowDate = new Date().toLocaleDateString('ja-JP');
//propsで渡された値を代入。ないときの処理
const {
title,
description,
image = undefined ?? defaultOgpImg.src ,
pubDate = undefined ?? nowDate,
updateDate = undefined ?? nowDate
} = Astro.props;
//imageがundefindのときはfavicon.svgを返す。
---
<!-- Global Metadata -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link rel="icon" type="image/vnd.microsoft.icon" href={favicon} />
<meta name="generator" content={Astro.generator} />
<meta http-equiv="Last-Modified" content={updateDate} />
<!-- Canonical URL
<link rel="canonical" href={canonicalURL} />
-->
<!-- Primary Meta Tags -->
<title>{title}</title>
<meta name="title" content={title} />
<meta name="description" content={description} />
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website" />
<meta property="og:url" content={Astro.url} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={new URL(image, Astro.url)} />
<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:url" content={Astro.url} />
<meta property="twitter:title" content={title} />
<meta property="twitter:description" content={description} />
<meta property="twitter:image" content={new URL(image, Astro.url)} />
<!-- robotにサイトマップを伝える -->
<link rel="sitemap" href="/sitemap-index.xml">
interface Props
このコードは、Astro コンポーネントで使用されるProps
インターフェースの定義です。インターフェースは、コンポーネントが props として受け取るデータの型を定義するために使用されます。
というGeminiの解説の通り、ここでPropsの定義を行っておきます。
/pages/index.astro → /layout/Layout.astro → /compornents/BaseHead.astro
index.astro でLayout.astroを呼び出す時にtitleやdescriptionを引数として指定、受け取ったLayout.astroはそのPropsを再度使ってBaseHead.astroを呼び出します。
BaseHead.astroを作ったら一旦 /pages/index.astroに直接記述して動くか確かめます。
---
import BaseHead from "../compornents/BaseHead.astro";
const res = await fetch('https://xxx.xxx/wp-json/wp/v2/posts?_embed'); //後ほど.envとかにサーバ情報は分離します。
const posts = await res.json();//ここ忘れがち。Jsonにコンバートしないとね。
---
<html lang="ja">
<head>
<BaseHead title="TopPage" description="This Page is HomePage" />
</head>
<body>
<h1 class=" text-lg font-serif font-bold">AstroPress</h1>
<ul>
{
posts.map((post:any) => (
<li>{post.title.rendered}</li>
))
}
</ul>
</body>
</html>
Title等がMetaに出力できていればOK。
AstroPress