🆔

Astroコンポーネントで一意なid属性を生成する

2022/09/25に公開

input タグの id 属性と label タグの for 属性、
タブUIにおけるタブパネルの id 属性とタブ(ボタン)の aria-controls 属性など、
対応する要素を示すために一意なidが必要になる場合があります。

また、当然ですが、同じコンポーネントが複数回使用されたときにはidが重複しないようにしておく必要があります。

AstroではNodeの機能である crypto.randomUUID() を使用して、以下のように実装できます。

環境

  • Astro 1.9.0
  • Node.js v16.16.0

サンプルコード

Checkbox.astro
---
import { randomUUID } from 'node:crypto';
const uuid = randomUUID();
---

<input id={uuid} type="checkbox" />
<label for={uuid}>チェック</label>

使用例

index.astro
<Checkbox />
<Checkbox />
<Checkbox />

↓ build

<input id="4dd3f8b2-e9ec-42ec-b803-90f7af25978e" type="checkbox">
<label for="4dd3f8b2-e9ec-42ec-b803-90f7af25978e">チェック</label>

<input id="0f33fae8-dcb9-4a19-b90c-a3043ab4c375" type="checkbox">
<label for="0f33fae8-dcb9-4a19-b90c-a3043ab4c375">チェック</label>

<input id="f95be492-c64f-4a82-973f-fabadc26fab7" type="checkbox">
<label for="f95be492-c64f-4a82-973f-fabadc26fab7">チェック</label>

コンポーネントを複数回使用したとしても、それぞれ別のidが生成されます。
(※見やすさのため改行を調整しています)

TypeScriptで使用する場合

'node:crypto' の型宣言がないぞ、と怒られてしまうので、
@types/node を導入して、型定義を取得します。

npm install @types/node

補足: node:crypto

cryptoはNodeの機能の一つです。
https://nodejs.org/dist/latest-v16.x/docs/api/crypto.html#cryptorandomuuidoptions

ちなみに、importは crypto 単体でも可能ですが、v14.13.1、v12.20.0以降 node: のimportが導入され、nodeの機能を使用していることをわかりやすく、またnpm packageと名前の衝突を起こさない形でimportすることができるようになっており、その記法を使用しています。
https://nodejs.org/api/esm.html#node-imports

なお、今回はAstroで使用するためNodeの機能として紹介しましたが、
ブラウザAPIとしても実装されています。
https://developer.mozilla.org/ja/docs/Web/API/Web_Crypto_API

GitHubで編集を提案

Discussion