Skip to content

Programmatically expose HTML tag attributes for bundle assets #22241

@nikolawork

Description

@nikolawork

Description

I'm building micro frontends where each bundle needs a loading script — a standalone .js file that dynamically adds all required <script>, <link>, and <div> elements to the DOM of a host page. This loading script is generated after the Vite build.

Currently, I generate these loading scripts by parsing the HTML files that Vite outputs using JSDOM, extracting the elements and their attributes, and rewriting them as JavaScript DOM manipulation code. This works, but it is error-prone and requires an HTML parsing dependency for what is essentially build metadata that Vite already knows.

Example

Given this source HTML entry point:

<div id="user-dashboard"></div>
<script type="module" src="./src/user-dashboard.ts"></script>

Vite generates this in dist/user-dashboard.html:

<script type="module" crossorigin src="/assets/user-dashboard-DMyRxV7X.js"></script>
<link rel="modulepreload" crossorigin href="/assets/BaseIcon-B5o5Ag_b.js">
<link rel="stylesheet" crossorigin href="/assets/BaseIcon-BL0lr_Hb.css">
<link rel="stylesheet" crossorigin href="/assets/user-dashboard-C-g5ZKi8.css">
<div id="user-dashboard"></div>

I then parse that HTML and transform it into a loading script (dist/user-dashboard.js) that a host page can load to inject the bundle:

{
  {
    const script = document.createElement('script');
    script.type = 'module';
    script.crossOrigin = '';
    script.src = '/assets/user-dashboard-DMyRxV7X.js';
    document.body.appendChild(script);
  }
  {
    const link = document.createElement('link');
    link.rel = 'modulepreload';
    link.crossOrigin = '';
    link.href = '/assets/BaseIcon-B5o5Ag_b.js';
    document.body.appendChild(link);
  }
  {
    const link = document.createElement('link');
    link.rel = 'stylesheet';
    link.crossOrigin = '';
    link.href = '/assets/BaseIcon-BL0lr_Hb.css';
    document.body.appendChild(link);
  }
  {
    const link = document.createElement('link');
    link.rel = 'stylesheet';
    link.crossOrigin = '';
    link.href = '/assets/user-dashboard-C-g5ZKi8.css';
    document.body.appendChild(link);
  }
}

The key information I need (which elements to create and what attributes they should have) is all decided by Vite, but I can only access it by parsing the generated HTML.

Suggested solution

Expose the HTML tags that Vite generates for each entry point as structured data, accessible from a plugin hook. For example, by adding a property to entry chunks in the bundle, like chunk.viteMetadata.htmlTags:

interface ChunkMetadata {
	importedAssets: Set<string>;
	importedCss: Set<string>;
	// New:
	htmlTags: Array<{
		tag: string;
		attrs: Record<string, string | boolean>;
	}>;
}

Alternative

No response

Additional context

No response

Validations

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions