Astroでブログを(ほぼ)ゼロJSにする
7378文字昨年
しかし,
Astroを選ぶ理由
Astroは、ブログやマーケティング、eコマースなど、コンテンツ駆動のウェブサイトを作成するためのウェブフレームワークです。Astroがあなたのウェブサイトに適しているであろう理由について学びます。
docs.astro.build
個人サイトをAstroで作り直し,ブログを開設した - 海の見える駅舎
このサイトを改修し,Astroを使って再構築し,ブログを設置した。
ha710.com
「外部
実は,
---
import { YouTube } from 'astro-embed';
---
<!-- body 要素内で -->
<YouTube id="dQw4w9WgXcQ" />
と
Astro Embed
High performance, rich media embed components. For your site, from the Astro community.
astro-embed.netlify.app
しかし
Twitter (X)
大昔
しかし,
X API pay-per-usage pricing and credits - X
The X API uses pay-per-usage pricing with no subscriptions. Buy credits, set spending limits, and earn up to 20% back in free xAI API credits.
docs.x.com
Xid
import { Client } from '@xdevplatform/xdk';
const client = new Client({ bearerToken: MY_XAPI_BEARER_TOKEN });
const response = await client.posts.getById(id, {
postFields: ['created_at', 'text'],
expansions: ['author_id', 'attachments.media_keys'],
userFields: ['username', 'name', 'profile_image_url', 'id'],
mediaFields: ['url', 'preview_image_url', 'type', 'variants', 'width', 'height', 'alt_text'],
});
if (response.errors) {
// error handling
}
const postText = response.data!.text!;
const postDate = new Date(response.data!.createdAt!);
// ...
こうして
HA710@8_7_10ウェブサイト整備のために今更 Astro 7 を触っているけど,Astro 5 の頃からアップデートしてなかったせいで新要素だらけだ
ニコニコ動画
Twitternicovideo
アプローチiframe
自動再生
Astroiframe
実は,window postMessage
ニコニコ動画埋め込みプレイヤーAPI非公式リファレンス
zenn.dev
もとhttps: script iframe
https://embed.nicovideo.jp/watch/sm****?persistence=1&oldScript=1&referer=https://example.com&from=0&allowProgrammaticFullScreen=1
でjsapi=1 playerId playerId NicovideoEmbed
---
interface Props {
readonly id: string;
}
const { id } = Astro.props;
const uID = getUniqueId();
---
<div data-nicovideo-id={id} data-unique-id={uID} tabindex="0">
<!-- ... -->
</div>
<a href={'https://www.nicovideo.jp/watch/' + id} target="_blank">→ニコニコ動画で再生する</a>
なお,uID playerId
iframe iframe postMessage
{
eventName: 'play',
sourceConnectorType: 1,
playerId: ****,
}
実際playerId
parentElement.addEventListener('click', () => {
// 既存のサムネイル等を非表示にする処理をし,id と uID を取得しておく ...
const iframe = document.createElement('iframe');
iframe.allowFullscreen = true;
iframe.allow = 'autoplay';
iframe.width = '720';
iframe.height = '480';
const iframeURL = new URL(`https://embed.nicovideo.jp/watch/${id}`);
iframeURL.searchParams.append('persistence', '1');
iframeURL.searchParams.append('oldScript', '1');
iframeURL.searchParams.append('referer', 'https://ha710.com/');
iframeURL.searchParams.append('from', '0');
iframeURL.searchParams.append('jsapi', '1');
iframeURL.searchParams.append('playerId', uID);
iframeURL.searchParams.append('allowProgrammaticFullScreen', '1');
iframe.src = iframeURL.href;
iframe.style.border = 'none';
parentElement.appendChild(iframe);
iframe.addEventListener('load', () => {
iframe.contentWindow?.postMessage({
eventName: 'play',
sourceConnectorType: 1,
playerId: uID,
}, 'https://embed.nicovideo.jp');
});
});
こう
デバイス規制動画への対処
いわゆるpostMessage
{
origin: 'https://embed.nicovideo.jp/',
data: {
data: { ... },
eventName: string,
playerId: string,
sourceConnectorType: number,
},
// ...
}
というdata
data: {
code: 'sensitive_video',
message: 'この動画はニコニコ動画でのみ視聴できます。',
raw: undefined,
}
というplayerId iframe
window.addEventListener('message', event => {
if (event.origin === 'https://embed.nicovideo.jp') {
if (event.data.data.code === 'sensitive_video') {
const playerId = event.data.playerId;
const playerWrapper = document.querySelector(`[data-unique-id="${playerId}"]`);
if (playerWrapper) {
const smID = (playerWrapper as HTMLElement).dataset.nicovideoId;
smID && window.open(`https://www.nicovideo.jp/watch/${smID}`);
}
}
}
});
最終
外部画像の最適化(おまけ)
ツイートimg href
Astro<Image /> pbs astro
import { defineConfig } from 'astro/config';
export default defineConfig({
image: {
domains: ['pbs.twimg.com'],
},
});
と
import { defineConfig } from 'astro/config';
export default defineConfig({
image: {
remotePatterns: [{ protocol: 'https' }],
},
});
と
Images
Learn how to use images in Astro.
docs.astro.build
脚注
-
YouTube
や ニコ ニコ 動画 など の よう な 動画 サイト の 埋 め 込み で あれ ば, 通常 は 縦横 の 大 き さ が あらかじめ 分 かって いる ので, ロード 前 から その 分 の 領域 を あけ て おく こと で レイアウト シフト を 防げる ( lazyloadを 設定 した 画像 の 縦横 サイズ を 指定 し て おく よう な もの だ)。 しかし, Twitter など の よう に 横 幅 は 指定 でき て も 縦 の 長 さ が わ から ない もの は どう しよう も ない。 ↑ -
気まぐれ
な イーロン ・ マスク が X API の 価格 改定 を 行 っ たら どう なる か? それ は 今 は 考え ない。 ↑ -
ツイート
の URL は https:/ / x . com / USERNAME / status / POSTID の よう な 構造 を し て いる が, この POSTIDの 部分 の こと。 ↑ -
ただし
ページ の 読み込み が 高速 に なる 反面, クリック し て から の 応答 性 は 下 が って しまう。 ↑ -
センシ
ティブ な 表現 が 含 ま れる と 判断 さ れ た 動画 の こと。 モバイル 版 を 中心 に 閲覧 制限 など が か か っ たり する。 ↑
《おわり》

