UI Architecture Philosophy ========================== This template takes a pragmatic, multi-tier approach to building user interfaces. Rather than forcing a single frontend paradigm, it offers a choice of tools: from simple Django templates to fully interactive React applications. The Core Principle ------------------ Not every page needs React. Not every page can get by with server rendered HTML. The key is matching your UI approach to the actual requirements: - **Prototyping and simple pages**: Django templates with Tailwind CSS and optional Alpine.js - **Highly interactive applications**: Vite-based SPAs (React, Vue) integrated via django-vite - **Marketing and content pages**: Pre-rendered static assets (Astro) served through Django Each approach is immediately available in this template. You choose based on your needs, not your tooling constraints. Tier 1: Django Templates (Simple) --------------------------------- For admin dashboards, forms, settings pages, and rapid prototyping, Django templates remain the simplest and most productive choice. django-tailwind-cli ^^^^^^^^^^^^^^^^^^^ This template includes `django-tailwind-cli`_ for Tailwind CSS integration **without webpack, Node.js in production, or complex build pipelines**. The Tailwind binary runs directly. No npm required. In development, a sidecar container watches for changes: .. code-block:: yaml # docker-compose.local.yml tailwind_sidecar: command: python manage.py tailwind watch For production, the custom ``collectstatic`` command automatically builds your CSS: .. code-block:: bash python manage.py collectstatic # Runs tailwind build first Alpine.js for Interactivity ^^^^^^^^^^^^^^^^^^^^^^^^^^^ When you need interactive behavior (dropdowns, modals, form validation) without a full JavaScript framework, `Alpine.js`_ is the recommended addition. Add it via CDN when needed: .. code-block:: html+jinja
Content here
Alpine.js is intentionally not included by default. Add it when your page needs it. This keeps simple pages simple. **Best for**: Admin interfaces, settings pages, forms, server-rendered content, rapid prototyping. Tier 2: Vite-Based SPAs (Interactive) ------------------------------------- When you need rich client-side interactivity (complex state management, real-time updates, data visualizations), reach for a proper frontend framework. django-vite Integration ^^^^^^^^^^^^^^^^^^^^^^^ The template uses `django-vite`_ to bridge Django and Vite based frontends: - **Hot Module Replacement** in development - **Manifest-based asset versioning** in production - **Django template integration** The Django template bootstraps your SPA: .. code-block:: html+django {% load django_vite %} {% vite_hmr_client app='myapp' %} {% vite_react_refresh app='myapp' %} {% vite_asset 'main.tsx' app='myapp' %}
The ``vite_hmr_client`` and ``vite_react_refresh`` tags enable hot reloading during development. In production, ``vite_asset`` reads from Vite's manifest to include cache-busted asset URLs. Vite Configuration ^^^^^^^^^^^^^^^^^^ The key Vite settings for Django integration: .. code-block:: typescript // vite.config.ts export default defineConfig({ base: '/static/myapp', // Matches Django's static URL build: { manifest: 'manifest.json', // Required for django-vite outDir: 'dist/myapp', }, }); Django Settings ^^^^^^^^^^^^^^^ Configure the django-vite app in settings: .. code-block:: python # settings/base.py DJANGO_VITE = { "myapp": { "dev_mode": DEBUG, "dev_server_port": 5173, "static_url_prefix": "myapp", "manifest_path": BASE_DIR / "apps/myapp/dist/myapp/manifest.json", }, } STATICFILES_DIRS = [ BASE_DIR / "apps/myapp/dist", # Include built assets ] **Best for**: Complex dashboards, real time applications, data-heavy UIs, anywhere React/Vue makes sense. Tier 3: Pre-Built Static Assets (Marketing) ------------------------------------------- For landing pages, marketing sites, and content heavy pages, pre-rendered static HTML offers the best performance and SEO. The template includes an Astro workspace for this purpose. Astro Configuration ^^^^^^^^^^^^^^^^^^^ Astro generates static HTML with optional interactive islands: .. code-block:: javascript // astro.config.mjs export default defineConfig({ integrations: [react()], // React islands for interactive components output: 'static', // Pre-render everything outDir: './dist', base: '/static/', // Django serves from here }); Serving from Django ^^^^^^^^^^^^^^^^^^^ Static pages can be served directly through Django's URL routing: .. code-block:: python from django.http import FileResponse, Http404 from django.conf import settings from pathlib import Path def serve_landing_page(request): """Serve pre-rendered Astro landing page.""" if settings.DEBUG: html_path = Path(settings.BASE_DIR) / "apps/landing/dist/index.html" else: html_path = Path(settings.STATIC_ROOT) / "index.html" if html_path.exists(): return FileResponse(html_path.open("rb"), content_type="text/html") raise Http404("Landing page not found. Run 'pnpm build' first.") urlpatterns = [ path("", serve_landing_page, name="home"), ] The Astro output directory is also added to ``STATICFILES_DIRS``, so ``collectstatic`` gathers all assets for production. **Best for**: Landing pages, marketing sites, documentation, SEO-critical content. Choosing the Right Approach --------------------------- +---------------------------+----------------------+----------------------+----------------------+ | Requirement | Django Templates | Vite SPA | Astro Static | +===========================+======================+======================+======================+ | Server-rendered HTML | Yes | No | Yes (pre-rendered) | +---------------------------+----------------------+----------------------+----------------------+ | SEO-friendly | Yes | Requires SSR | Yes | +---------------------------+----------------------+----------------------+----------------------+ | Complex client state | No (use Alpine.js) | Yes | Limited (islands) | +---------------------------+----------------------+----------------------+----------------------+ | Build step required | No | Yes | Yes | +---------------------------+----------------------+----------------------+----------------------+ | Hot module replacement | No | Yes | Yes | +---------------------------+----------------------+----------------------+----------------------+ | TypeScript support | No | Yes | Yes | +---------------------------+----------------------+----------------------+----------------------+ | Best for | Admin, forms, | Dashboards, apps, | Landing pages, | | | prototypes | complex UIs | marketing | +---------------------------+----------------------+----------------------+----------------------+ The Monorepo Advantage ---------------------- With Turborepo, all frontend approaches share: - **Common component library** in ``packages/ui/`` (Radix UI + shadcn components) - **Shared TypeScript, ESLint, and Prettier configs** - **Single ``pnpm build`` command** builds everything - **Unified dependency management** via pnpm workspaces This means your landing page (Astro), main application (React), and Django admin can all use the same design system without duplication. Further Reading --------------- - `django-tailwind-cli`_ — Tailwind CSS without Node.js - `django-vite`_ — Vite integration for Django - `Alpine.js`_ — Minimal JavaScript framework - `Astro`_ — Static site generator with islands architecture .. _django-tailwind-cli: https://github.com/oliverandrich/django-tailwind-cli .. _django-vite: https://github.com/MrBin99/django-vite .. _Alpine.js: https://alpinejs.dev/ .. _Astro: https://astro.build/