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

Menu

twitter X