HTML Transformation¶
HTML transformation utilities for injecting scripts, metadata, and attributes into HTML documents.
Common use cases: - Inject CSRF tokens - Inject Inertia.js page props - Add data attributes to elements - Inject JSON data as global variables
HTML transformation and injection utilities for SPA output.
Regex patterns are compiled once at import time for performance.
- litestar_vite.html_transform.inject_head_script(html: str, script: str, *, escape: bool = True, nonce: str | None = None) str[source]¶
Inject a script tag before the closing </head> tag.
- Parameters:
- Returns:
The HTML with the injected script. If
</head>is not found, falls back to injecting before</html>. If neither is found, appends the script at the end. Returns the original HTML unchanged ifscriptis empty.
Example
html = inject_head_script(html, “window.__DATA__ = {foo: 1};”)
- litestar_vite.html_transform.inject_head_html(html: str, content: str) str[source]¶
Inject raw HTML into the
<head>section.This is used for Inertia SSR, where the SSR server returns an array of HTML strings (typically
<title>,<meta>, etc.) that must be placed in the final HTML response.
- litestar_vite.html_transform.inject_body_content(html: str, content: str, *, position: str = 'end') str[source]¶
Inject content into the body element.
- Parameters:
- Returns:
The HTML with the injected content. Returns the original HTML unchanged if
contentis empty or if no<body>tag is found.
Example
html = inject_body_content(html, ‘<div id=”portal”></div>’, position=”end”)
- litestar_vite.html_transform.set_data_attribute(html: str, selector: str, attr: str, value: str) str[source]¶
Set a data attribute on an element matching the selector.
This function supports simple ID selectors (#id) and element selectors (div). For complex selectors, consider using a proper HTML parser.
- Parameters:
- Returns:
The HTML with the attribute set. If the attribute already exists, it is replaced. Returns the original HTML unchanged if
selectororattris empty, or if no matching element is found.
Note
Only the first matching element is modified. The value is automatically escaped to prevent XSS vulnerabilities.
Example
html = set_data_attribute(html, “#app”, “data-page”, ‘{“component”:”Home”}’)
- litestar_vite.html_transform.set_element_inner_html(html: str, selector: str, content: str) str[source]¶
Replace the inner HTML of an element matching the selector.
Supports only simple ID selectors (
#app). This is intentionally limited to avoid the overhead and edge cases of a full HTML parser.
- litestar_vite.html_transform.inject_page_script(html: str, json_data: str, *, nonce: str | None = None, script_id: str = 'app_page') str[source]¶
Inject page data as a JSON script element before
</body>.This is an Inertia.js v2.3+ optimization that embeds page data in a
<script type="application/json">element instead of adata-pageattribute. This provides ~37% payload reduction for large pages by avoiding HTML entity escaping.The script element is inserted before
</body>with: -type="application/json"(non-executable, just data) -id="app_page"(Inertia’s expected ID for useScriptElementForInitialPage) - Optionalnoncefor CSP compliance- Parameters:
- Returns:
The HTML with the script element injected before
</body>. Falls back to appending at the end if no</body>tag is found.
Note
The JSON content is escaped to prevent XSS via
</script>injection. Sequences like</are replaced with<\\/(escaped forward slash) which is valid JSON and prevents HTML parser issues.Example
html = inject_page_script(html, ‘{“component”:”Home”,”props”:{}}’)
- litestar_vite.html_transform.inject_json_script(html: str, var_name: str, data: dict[str, Any], *, nonce: str | None = None) str[source]¶
Inject a script that sets a global JavaScript variable to JSON data.
This is a convenience function for injecting structured data into the page. The data is serialized with compact JSON (no extra whitespace) and non-ASCII characters are preserved.
- Parameters:
- Returns:
The HTML with the injected script in the
<head>section. Falls back to injecting before</html>or at the end if no</head>is found.
Note
The script content is NOT escaped to preserve valid JSON. Ensure that
datadoes not contain user-controlled content that could include malicious</script>sequences.Example
html = inject_json_script(html, “__ROUTES__”, {“home”: “/”, “about”: “/about”})
- litestar_vite.html_transform.inject_vite_dev_scripts(html: str, vite_url: str, *, asset_url: str = '/static/', is_react: bool = False, csp_nonce: str | None = None, resource_dir: str | None = None) str[source]¶
Inject Vite dev server scripts for HMR support.
This function injects the necessary scripts for Vite’s Hot Module Replacement (HMR) to work when serving HTML from the backend (e.g., in hybrid/Inertia mode). The scripts are injected into the
<head>section.For React apps, a preamble script is injected before the Vite client to enable React Fast Refresh.
Scripts are injected as relative URLs using the
asset_urlprefix. This routes them through Litestar’s proxy middleware, which forwards to Vite with the correct base path handling.When
resource_diris provided, entry point script URLs are also transformed to include the asset URL prefix (e.g.,/resources/main.tsxbecomes/static/resources/main.tsx).- Parameters:
html¶ – The HTML document.
vite_url¶ – The Vite dev server URL (kept for backward compatibility, unused).
asset_url¶ – The asset URL prefix (e.g., “/static/”). Scripts are served at
{asset_url}@vite/clientetc.is_react¶ – Whether to inject the React Fast Refresh preamble.
csp_nonce¶ – Optional CSP nonce to add to injected
<script>tags.resource_dir¶ – Optional resource directory name (e.g., “resources”, “src”). When provided, script sources starting with
/{resource_dir}/are prefixed withasset_url.
- Returns:
The HTML with Vite dev scripts injected. Scripts are inserted before
</head>when present, otherwise before</html>or at the end.
Example
html = inject_vite_dev_scripts(html, “”, asset_url=”/static/”, is_react=True)
- litestar_vite.html_transform.transform_asset_urls(html: str, manifest: dict[str, Any], asset_url: str = '/static/', base_url: str | None = None) str[source]¶
Transform asset URLs in HTML based on Vite manifest.
This function replaces source asset paths (e.g., /resources/main.tsx) with their hashed production equivalents from the Vite manifest (e.g., /static/assets/main-C-_c4FS5.js).
This is essential for production mode when using Vite’s library mode (input: [“resources/main.tsx”]) where Vite doesn’t transform index.html.
- Parameters:
html¶ – The HTML document to transform.
manifest¶ – The Vite manifest dictionary mapping source paths to output. Each entry should have a
filekey with the hashed output path.asset_url¶ – Base URL for assets (default “/static/”).
base_url¶ – Optional CDN base URL override for production assets. When provided, takes precedence over
asset_url.
- Returns:
The HTML with transformed asset URLs. Returns the original HTML unchanged if
manifestis empty. Asset paths not found in the manifest are left unchanged (no error is raised).
Note
This function transforms
<script src="...">and<link href="...">attributes. Leading slashes in source paths are normalized for manifest lookup (e.g., “/resources/main.tsx” matches “resources/main.tsx” in manifest).Example
manifest = {“resources/main.tsx”: {“file”: “assets/main-abc123.js”}} html = ‘<script type=”module” src=”/resources/main.tsx”></script>’ result = transform_asset_urls(html, manifest) # Result: ‘<script type=”module” src=”/static/assets/main-abc123.js”></script>’