Component Fragment Rendering#
The litestar_vite.fragments package provides server-side rendering of isolated UI components (React, Vue, Svelte, Astro) into HTML fragments for HTMX partial swaps and Jinja2 templates.
Production components must be compiled and registered in the worker. Islands also require a browser registry and framework hydration adapter; Astro supports static fragments only. See HTMX & Server-Rendered UI Component Fragments for both build entries.
Fragment Engine & APIs#
UI component fragment rendering engine for Litestar Vite.
- class litestar_vite.fragments.ComponentResponse[source]#
-
HTTP Response that renders a server-side component fragment.
Renders UI component fragments (React, Vue, Svelte, Astro) into HTML markup for HTMX partial swaps and micro-frontend architectures.
- __init__(component: str, props: dict[str, Any] | None = None, mode: Literal['static', 'island'] = 'static', status_code: int = 200, headers: ResponseHeaders | None = None, cookies: ResponseCookies | None = None, background: BackgroundTask | BackgroundTasks | None = None, encoding: str = 'utf-8') None[source]#
Initialize the ComponentResponse.
- Parameters:
component¶ – Path to the component entrypoint.
props¶ – Optional dictionary of component props.
mode¶ – Rendering mode (‘static’ for zero JS or ‘island’ for interactive).
status_code¶ – HTTP response status code, defaults to 200.
headers¶ – Optional dictionary or sequence of response headers.
cookies¶ – Optional response cookies.
background¶ – Optional background task to execute after response completion.
encoding¶ – Content character encoding, defaults to ‘utf-8’.
- to_asgi_response(app: Any, request: Request[Any, Any, Any], *, background: BackgroundTask | BackgroundTasks | None = None, cookies: Any = None, encoded_headers: Any = None, headers: dict[str, str] | None = None, is_head_response: bool = False, media_type: Any = None, status_code: int | None = None, type_encoders: Any = None) ASGIResponse[source]#
Construct the ASGI response that renders the component fragment.
- Parameters:
app¶ – The Litestar application instance.
request¶ – The incoming request.
background¶ – Optional background tasks.
cookies¶ – Optional cookies.
encoded_headers¶ – Optional encoded headers.
headers¶ – Optional headers dictionary.
is_head_response¶ – Whether the request is a HEAD request.
media_type¶ – Response media type.
status_code¶ – Optional status code override.
type_encoders¶ – Type encoders mapping.
- Returns:
An ASGIResponse callable that executes the fragment rendering.
- render(content: Any, media_type: str, enc_hook: Serializer = <function default_serializer>) bytes#
Handle the rendering of content into a bytes string.
- Returns:
An encoded bytes string
- set_cookie(key: str | Cookie, value: str | None = None, max_age: int | None = None, expires: int | None = None, path: str = '/', domain: str | None = None, secure: bool = False, httponly: bool = False, samesite: Literal['lax', 'strict', 'none'] = 'lax') None#
Set a cookie on the response. If passed a
Cookieinstance, keyword arguments will be ignored.- Parameters:
key¶ – Key for the cookie or a
Cookieinstance.value¶ – Value for the cookie, if none given defaults to empty string.
max_age¶ – Maximal age of the cookie before its invalidated.
expires¶ – Seconds from now until the cookie expires.
path¶ – Path fragment that must exist in the request url for the cookie to be valid. Defaults to
/.domain¶ – Domain for which the cookie is valid.
secure¶ – Https is required for the cookie.
httponly¶ – Forbids javascript to access the cookie via
document.cookie.samesite¶ – Controls whether a cookie is sent with cross-site requests. Defaults to
lax.
- Returns:
None.
- class litestar_vite.fragments.FragmentEngine[source]#
Bases:
objectOrchestrates rendering UI component fragments over IPC transports.
- __init__(config: ViteConfig, asset_loader: ViteAssetLoader, transport: BaseIPCTransport | None = None, *, transport_factory: Callable[[], BaseIPCTransport] | None = None) None[source]#
Initialize the fragment engine with configuration and asset loader.
- get_component_css_urls(component: str) list[str][source]#
Extract all CSS file URLs for a component from manifest or dev server.
In production mode, looks up the component in the parsed manifest.json, collects its direct ‘css’ array, and recursively traverses ‘imports’ chunks to collect imported CSS dependencies with cycle detection. Normalizes paths using POSIX formatting to support Windows environments.
In development mode, returns the direct component CSS URL or Vite dev server URL only for dedicated stylesheet files, omitting component entries such as .vue and .tsx to prevent browser MIME type rejections.
- Parameters:
component¶ – Relative path to the component, e.g. ‘components/UserProfile.vue’.
- Returns:
List of resolved CSS URLs.
- generate_component_css_tags(component: str, newline: str = '\n') str[source]#
Generate HTML link tags for a component’s scoped styles.
- async render_fragment(component: str, props: dict[str, Any] | None = None, mode: Literal['static', 'island'] = 'static') str[source]#
Render a UI component fragment to HTML asynchronously.
Sends render request to the background IPC worker, retrieves the rendered markup, and prepends scoped CSS link tags resolved from manifest.json.
- Parameters:
- Returns:
Rendered HTML string with scoped CSS links prepended.
- Raises:
ImproperlyConfiguredException – If the IPC worker reports a render error.
- render_fragment_sync(component: str, props: dict[str, Any] | None = None, mode: Literal['static', 'island'] = 'static') str[source]#
Render a UI component fragment synchronously for template engines.
Executes the async render_fragment method on the worker loop using anyio. Falls back to anyio.run when no event loop is active on the current thread.
- litestar_vite.fragments.render_fragment(context: Mapping[str, Any], /, component: str, props: dict[str, Any] | None = None, mode: Literal['static', 'island'] = 'static', **kwargs: Any) Markup#
Render a component fragment within a Jinja2 template.
Merges explicit props with keyword arguments passed to the template callable.
- Example in Jinja template:
{{ vite_fragment(“components/UserProfile.vue”, user=user) }} {{ vite_fragment(“components/Counter.tsx”, props={“initial”: 0}, mode=”island”) }}
- Parameters:
context¶ – The Jinja2 template context containing the request.
component¶ – Relative path to the component entrypoint.
props¶ – Optional dictionary of component props.
mode¶ – Rendering mode (‘static’ for HTML only or ‘island’ for interactive).
**kwargs¶ – Additional props passed as keyword arguments.
- Returns:
Markup-safe rendered HTML string with scoped styles.
- litestar_vite.fragments.vite_fragment(context: Mapping[str, Any], /, component: str, props: dict[str, Any] | None = None, mode: Literal['static', 'island'] = 'static', **kwargs: Any) Markup[source]#
Render a component fragment within a Jinja2 template.
Merges explicit props with keyword arguments passed to the template callable.
- Example in Jinja template:
{{ vite_fragment(“components/UserProfile.vue”, user=user) }} {{ vite_fragment(“components/Counter.tsx”, props={“initial”: 0}, mode=”island”) }}
- Parameters:
context¶ – The Jinja2 template context containing the request.
component¶ – Relative path to the component entrypoint.
props¶ – Optional dictionary of component props.
mode¶ – Rendering mode (‘static’ for HTML only or ‘island’ for interactive).
**kwargs¶ – Additional props passed as keyword arguments.
- Returns:
Markup-safe rendered HTML string with scoped styles.
Handler Usage#
Return a ComponentResponse directly from any Litestar route handler:
from litestar import get
from litestar_vite import ComponentResponse
@get("/profile/{user_id:int}")
async def get_profile(user_id: int) -> ComponentResponse:
"""Render a Vue user profile component into an HTML fragment."""
return ComponentResponse(
component="components/UserProfile.vue",
props={"userId": user_id},
mode="static",
)
Jinja Template Callable#
Render component fragments directly in Jinja templates using vite_fragment():
<div class="user-container">
{{ vite_fragment("components/UserProfile.vue", user=current_user, mode="static") }}
</div>