Skip to content

Conversation

@petermorrowdev
Copy link

@petermorrowdev petermorrowdev commented Sep 7, 2025

Add new Django template tag to generate tags for Vite-bundled assets, enabling early loading of critical resources like fonts and images to improve page load performance.

  • Add assets field to ManifestEntry to support asset references in Vite manifest
  • Implement generate_preload_assets_tags method in DjangoViteAppClient
  • Add vite_preload_assets templatetag w/ file_ext, as_type and **kwargs
  • Custom args like crossorigin for fonts supported via **kwargs
  • Automatic MIME type detection using mimetypes from standard library

Usage: {% vite_preload_assets 'src/entry.js' file_ext='.woff2' as_type='font' %}


This template tag addresses the performance issue where fonts loaded via CSS @font-face rules don't start downloading until after the CSS is parsed, causing layout shifts when fonts swap in. For example:

You can put this in the <head> of a base template

{% vite_preload_assets 'theme/fonts.css.ts' file_ext=".woff2" as_type="font" crossorigin="anonymous" %}

Where theme/fonts.css.ts is like:

import { globalFontFace } from '@vanilla-extract/css';

const fontDefinitions = [
  {
    familyName: 'MyFont`',
    pathName: 'myfont',
    weights: [200, 300, 400, 500, 600, 700, 800],
    styles: ['normal', 'italic'],
  },
  // ... other essential fonts
];

function generateFontFaces(font: (typeof fontDefinitions)[number]) {
  for (const weight of font.weights) {
    for (const style of font.styles) {
      const fontFile = `${font.pathName}-latin-${weight}-${style}.woff2`;
      // you'd have to `npm install @fontsource/myfont` for this to work
      const path = `@fontsource/${font.pathName}/files/${fontFile}`;

      globalFontFace(font.familyName, {
        fontStyle: style,
        fontWeight: weight,
        // sets `font-display: block` to avoid CLS
        fontDisplay: 'block',
        src: `url('${path}') format('woff2')`,
      });
    }
  }
}

fontDefinitions.forEach(generateFontFaces);

Also, the template tag name might cause confusion with the existing vite_preload_asset (no "s") tag, so maybe I should rename it to vite_preload_links or something..?

Anyways, I hope that extra context helps explain why I'm making this contribution. I've tried my best to follow the repo's existing patterns and included unit tests to maintain the project's high test coverage.

Please let me know if you have any questions or would like me to make any changes.

Add new Django template tag to generate <link rel="preload"> tags for
Vite-bundled assets, enabling early loading of critical resources like
fonts and images to improve page load performance.

- Add `assets` field to ManifestEntry to support asset references in Vite manifest
- Implement `generate_preload_assets_tags` method in `DjangoViteAppClient`
- Add `vite_preload_assets` templatetag w/ `file_ext`, `as_type` and `**kwargs`
- Custom args like `crossorigin` for fonts supported via `**kwargs`
- Automatic MIME type detection using `mimetypes` from standard library

Usage: {% vite_preload_assets 'src/entry.js' file_ext='.woff2' as_type='font' %}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant