feat(vite): auto-load templates + Template helper + config flag#133
Merged
Conversation
ViteProvider now binds a Jinja2Templates engine out of the box so fresh apps get a working template engine and the vite() globals are injected during boot. An existing 'templates' binding always wins, keeping the change backward-compatible. - Add ViteConfig.template and ViteConfig.templates_directory flags - Auto-bind templates in ViteProvider.register() with a guarded jinja2 import that points users to the [vite] extra - Add Template class and template() helper (Laravel view()-style) that resolve the request from context or a per-request ContextVar - Add RequestContextMiddleware to expose the active request - Export Template and template from fastapi_startkit.vite - Cover the new behaviour with tests - Simplify example/vite-app to rely on the auto-bound engine
This was referenced Jun 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes the root cause where a fresh app got no template engine:
ViteProvidernever boundJinja2Templates, andregister_jinja_directives()only injected thevite()globals if atemplatesbinding already existed.ViteProvidernow provides a template engine out of the box and ships a Laravelview()-style helper for rendering.Changes
vite/config/vite.py): addtemplate: bool = Trueandtemplates_directory: str = "resources/templates".vite/providers/provider.py): inregister(), whentemplateis enabled and notemplatesbinding exists yet, buildJinja2Templates(base_path / templates_directory)and bind it astemplates. The jinja2 import is guarded with a clear error pointing topip install fastapi-startkit[vite].register_jinja_directives()is unchanged — it now finds the binding and injects thevite()globals. An existing binding always wins, so this is fully backward-compatible.vite/template.py): newtemplate(name, context=None)module helper andTemplate.render(name, context=None)static class. The request is resolved implicitly — fromcontext["request"]if present, otherwise from a per-requestContextVar— with a fallback to the legacy StarletteTemplateResponsesignature.fastapi/context.py,fastapi/middleware.py): a generalcurrent_requestContextVarset byRequestContextMiddleware, registered inFastAPIProvider.boot(), so helpers can resolve the active request without it being passed explicitly.vite/__init__.py):Templateandtemplateare now importable fromfastapi_startkit.vite.example/vite-app): drops the manualtemplatesbind and uses the auto-bound engine +template()helper.Tests
New
tests/vite/test_template.pycovers: bindstemplateswhen enabled and none pre-bound; respects an existing binding; skips whentemplate=False;vite()globals present after boot;template()andTemplate.render()return aTemplateResponse(via explicit request and via the ContextVar); and the clear error when no engine is bound.uv run pytest tests/vite/ -v→ 38 passedfail_under)