facebook/docusaurus · error · Error

Error loading ${JSON.stringify(val)}, "${htmlTag.tagName}" i

Error message

Error loading ${JSON.stringify(val)}, "${htmlTag.tagName}" is not a valid HTML tag. Either use a valid "tagName" or set "customElement: true".

What it means

Thrown by `assertIsHtmlTagObject` when the object has a string `tagName` but that name is not in Docusaurus's allowlist of known HTML tags, and `customElement: true` is not set. This guards against typos and encourages explicit opt-in for custom element names (e.g. web components).

Source

Thrown at packages/docusaurus/src/server/htmlTags.ts:37

// TODO this should be done at config validation time, not here
function assertIsHtmlTagObject(val: unknown): asserts val is HtmlTagObject {
  if (typeof val !== 'object' || !val) {
    throw new Error(`"${val}" is not a valid HTML tag object.`);
  }
  const htmlTag = val as HtmlTagObject;
  if (typeof htmlTag.tagName !== 'string') {
    throw new Error(
      `${JSON.stringify(
        val,
      )} is not a valid HTML tag object. "tagName" must be defined as a string.`,
    );
  }
  if (
    !htmlTag.customElement &&
    !(htmlTags as string[]).includes(htmlTag.tagName)
  ) {
    throw new Error(
      `Error loading ${JSON.stringify(val)}, "${
        htmlTag.tagName
      }" is not a valid HTML tag. Either use a valid "tagName" or set "customElement: true".`,
    );
  }
}

function hashRouterAbsoluteToRelativeTagAttribute(
  name: string,
  value: string,
): string {
  if ((name === 'src' || name === 'href') && value.startsWith('/')) {
    return `.${value}`;
  }
  return value;
}

function htmlTagObjectToString({

View on GitHub (pinned to 3f483e80e3)

Solutions

  1. Fix typos in the `tagName` to match a standard HTML element.
  2. For legitimate custom elements, add `customElement: true` to the tag object.
  3. Confirm the tag name against the HTML spec / your web component definition.

Example fix

// before
headTags: [{tagName: 'my-analytics', attributes: {id: 'x'}}],
// after
headTags: [{tagName: 'my-analytics', attributes: {id: 'x'}, customElement: true}],
Defensive patterns

Strategy: validation

Validate before calling

const CUSTOM = new Set(['my-widget','my-analytics']);
function validateTag(t: HtmlTagObject) {
  if (!t.customElement && !KNOWN_HTML_TAGS.has(t.tagName) && !CUSTOM.has(t.tagName)) {
    throw new Error(`Unknown tagName ${t.tagName}; set customElement: true if intentional`);
  }
}

Type guard

function isAllowedTagName(tag: {tagName: string; customElement?: boolean}): boolean {
  return Boolean(tag.customElement) || KNOWN_HTML_TAGS.has(tag.tagName);
}

Prevention

When it happens

Trigger: Using a `tagName` that is neither a standard HTML element nor flagged as custom — for instance `{tagName: 'my-widget'}` without `customElement: true`. The check at htmlTags.ts:37-44 fires when `!htmlTag.customElement && !(htmlTags as string[]).includes(htmlTag.tagName)`.

Common situations: Registering a web component / custom element in `headTags`; a typo like `'scritp'`; using a framework-specific tag (e.g. an Astro/island component name) without opting in.

Related errors


AI-assisted analysis of facebook/docusaurus@3f483e80e3 (2026-08-12). Data as JSON: /api/errors/e89698cbfe652436. Report an issue: GitHub.