published: 2022/5/20 update: 2022/6/12
ブログでよくある、関係のある記事をランダムで記事の一番下につけたかったのですが、静的サイトだとどうすればいいのかよくわかりませんでした。一つは毎回ServersideProps
呼ぶ、ということだと思うんですが、それとgetStaticsProps
の併用、どうやるんだ?ってところでよくわからなくなりました。毎回サーバーサイドレンダリングしてると、遅くなりそうで嫌なので...
そこで、今回とったアプローチは、Next.jsでAPIをまず実装し、それをamp-list
を使ってfetchしてその結果をレンダリングするというアプローチを取りました。
amp-list
は、AMPの拡張コンポーネントでJSONエンドポイントから動的にデータを取得し、amp-mustache
のtemplateを使用してレンダリングを行うことができます。
公式ドキュメント(amp-list, amp-mustache)の例は以下の感じです。
<amp-list width="auto"
height="100"
layout="fixed-height"
src="/static/inline-examples/data/amp-list-urls.json">
<template type="amp-mustache">
<div class="url-entry">
<a href="{{url}}">{{title}}</a>
</div>
</template>
</amp-list>
使用しているJSONは以下
{
"items": [
{
"title": "AMP YouTube Channel",
"url": "https://www.youtube.com/channel/UCXPBsjgKKG2HqsKBhWA4uQw"
},
{
"title": "AMP.dev",
"url": "https://amp.dev/"
},
{
"title": "AMP Validator",
"url": "https://validator.amp.dev/"
},
{
"title": "AMP Playground",
"url": "https://playground.amp.dev/"
}
]
}
基本的には、<amp-list>
内でレイアウトとエンドポイントを指定し、<template type="amp-mustache">
内でどういうふうにレンダリングするかを決めます。
amp-mustache
では、以下のように変数を利用できます。
{{変数名}}
<template type="amp-mustache">
Hello {{world}}!
</template>
{{#section}}{{/section}}
<template type="amp-mustache">
{{#world}}
Hello {{world}}!
{{/#world}}
</template>
{{^section}}{{/section}}
<template type="amp-mustache">
{{^world}}
No World!
{{/#world}}
</template>
JSX内ではこれらのテンプレートは
<template type="amp-mustache">
Hello {"{{world}}"}!
</template>;
のように利用できます。
これらのことから、/api/otherarticles
のようなエンドポイントを作成し、そこから
[
{
"title": "test post",
"url": "/posts/test"
}
]
のようなものを返すことにします。
そうするとamp-list
の実装は
<amp-list
width="auto"
height="200"
layout="fixed-height"
src={`/api/otherarticles`}
items="."
>
{/* @ts-ignore */}
<template type="amp-mustache">
title={"{{title}}"}
url={"{{url}}"}
</template>
</amp-list>;
のようにすればよいです。
Next.jsのAPIは、pages/api/
下にts
などのファイルを作ればエンドポイントが作成できます。
export default function handler(req, res) {
const articles = {
title: "test post",
url: "/posts/test"
}
res.status(200).json(articles)
}
のような感じです。
実際の実装では、Next.jsで作ってみたブログに検索機能を導入するのような感じでキャッシュを作成しておいて、そのキャッシュを参照してランダムな配列から規定数のファイルを取り出しています。このブログのその部分の実装はgithubにあります。
記事に間違い等ありましたら、お気軽に以下までご連絡ください
E-mail: illumination.k.27|gmail.com ("|" replaced to "@")
Twitter: @illuminationK
当HPを応援してくれる方は下のリンクからお布施をいただけると非常に励みになります。
OfuseCopyright © illumination-k 2020-2022.