diff --git a/components/button/pure.js b/components/button/pure.js index 768016a01..d85e6dc88 100644 --- a/components/button/pure.js +++ b/components/button/pure.js @@ -1,7 +1,7 @@ import { html, nothing } from "lit"; import { ifDefined } from "lit/directives/if-defined.js"; -import { randomIdString } from "../utils/index.js"; +import { deterministicIdString } from "../utils/index.js"; /** * @param {object} options @@ -28,7 +28,10 @@ export default function Button({ variant = "primary", action, }) { - const labelId = randomIdString("label-"); + const labelId = deterministicIdString( + `button-${typeof label === "string" ? label : "btn"}-${href || ""}`, + "label-", + ); const iconElement = icon ? html`${icon}` : nothing; diff --git a/components/compat-table/element.js b/components/compat-table/element.js index b50aadbb8..668ec2f7a 100644 --- a/components/compat-table/element.js +++ b/components/compat-table/element.js @@ -4,7 +4,7 @@ import { unsafeHTML } from "lit/directives/unsafe-html.js"; import { L10nMixin } from "../../l10n/mixin.js"; -import { randomIdString } from "../utils/index.js"; +import { deterministicIdString } from "../utils/index.js"; import { DEFAULT_LOCALE, ISSUE_METADATA_TEMPLATE } from "./constants.js"; import styles from "./element.css?lit"; @@ -469,7 +469,10 @@ export class MDNCompatTable extends L10nMixin(LitElement) { version_added: false, }; - const timelineId = randomIdString("timeline-"); + const timelineId = deterministicIdString( + `timeline-${name}-${browserName}`, + "timeline-", + ); const supportClassName = getSupportClassName(support, browser); const notes = this._renderNotes(browser, support); diff --git a/components/dropdown/element.js b/components/dropdown/element.js index d4f1bb98c..ad08304b5 100644 --- a/components/dropdown/element.js +++ b/components/dropdown/element.js @@ -1,9 +1,12 @@ import { LitElement, html } from "lit"; -import { randomIdString } from "../utils/index.js"; +import { deterministicIdString } from "../utils/index.js"; import styles from "./element.css?lit"; +// Counter for generating unique dropdown IDs during SSR +let dropdownCounter = 0; + /** * This element has two slots, which should take a single element each. * The element in the `dropdown` slot is hidden by default, @@ -30,6 +33,8 @@ export class MDNDropdown extends LitElement { super(); this.open = false; this.loaded = false; + // Assign a unique instance ID for deterministic SSR rendering + this._instanceId = dropdownCounter++; } get _buttonSlotElements() { @@ -70,7 +75,7 @@ export class MDNDropdown extends LitElement { _setAriaAttributes() { let id = this._dropdownSlotElements.find((element) => element.id)?.id; if (!id) { - id = randomIdString("uid_"); + id = deterministicIdString(this._instanceId, "dropdown-"); this._dropdownSlotElements[0]?.setAttribute("id", id); } for (const element of this._buttonSlotElements) { diff --git a/components/interactive-example/with-choices.js b/components/interactive-example/with-choices.js index 50bc6d472..b6facefc5 100644 --- a/components/interactive-example/with-choices.js +++ b/components/interactive-example/with-choices.js @@ -5,7 +5,7 @@ import { ref } from "lit/directives/ref.js"; import { L10nMixin } from "../../l10n/mixin.js"; import { MDNPlayEditor } from "../play-editor/element.js"; -import { randomIdString } from "../utils/index.js"; +import { deterministicIdString } from "../utils/index.js"; import { isCSSSupported } from "./utils.js"; @@ -111,7 +111,7 @@ export const InteractiveExampleWithChoices = (Base) => } #render() { - const id = randomIdString(); + const id = deterministicIdString(`choices-${this.name}`, "ix-"); return html`