Skip to content

feat: self-host font for better privacy#2540

Merged
gauthier-th merged 5 commits intoseerr-team:developfrom
caillou:2438-bundle-fonts
Feb 27, 2026
Merged

feat: self-host font for better privacy#2540
gauthier-th merged 5 commits intoseerr-team:developfrom
caillou:2438-bundle-fonts

Conversation

@caillou
Copy link
Copy Markdown
Contributor

@caillou caillou commented Feb 20, 2026

Description

After trying Next's font optimization to self-host the font, I have decided to use the @fontsource-variable/inter package dependency for self-hosting the Inter font.

It is then served by us rather through Google.

Additionally, Google fonts were removed from mail templates.

How Has This Been Tested?

This has been tested in a local dev environment.

  • I have read and followed the contribution guidelines.
  • Disclosed any use of AI (see our policy)
  • I have updated the documentation accordingly.
  • All new and existing tests passed.
  • Successful build pnpm build
  • Translation keys pnpm i18n:extract
  • Database migration (if required)

Summary by CodeRabbit

  • Chores
    • Switched the app to use the Inter Variable font as the preferred local font for more consistent loading and rendering.
    • Added the Inter variable font package to the project.
    • Removed external Google Fonts and updated email templates to use a broader system font stack for more reliable cross-platform rendering.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 20, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 98f7259 and 3aeb8ec.

📒 Files selected for processing (1)
  • src/pages/_document.tsx

📝 Walkthrough

Walkthrough

Replaces external Google-hosted Inter font with a locally bundled variable Inter font: adds @fontsource-variable/inter, imports it in the app, removes Google Fonts links from _document and email templates, and updates Tailwind and email font-family fallbacks.

Changes

Cohort / File(s) Summary
Package & App
package.json, src/pages/_app.tsx, src/pages/_document.tsx, tailwind.config.js
Added dependency @fontsource-variable/inter; import of the variable Inter font in _app.tsx; removed Google Fonts preload/stylesheet from _document.tsx; changed Tailwind sans to Inter Variable.
Email Templates
server/templates/email/generatedpassword/html.pug, server/templates/email/media-issue/html.pug, server/templates/email/media-request/html.pug, server/templates/email/resetpassword/html.pug, server/templates/email/test-email/html.pug
Removed external Google Fonts link and expanded table font-family to Inter, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Helvetica Neue", Arial, sans-serif.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I tucked Inter into my cozy lair,

No distant calls, no fonts to share.
Variable threads, local and light,
Hopping quiet through day and night. 🎨🐇

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: self-host font for better privacy' directly summarizes the main change: migrating from Google Fonts to a self-hosted font solution for improved privacy.
Linked Issues check ✅ Passed The PR successfully implements the core requirement from issue #2438: bundling and self-hosting the Inter font to eliminate external connections to fonts.gstatic.com and improve user privacy.
Out of Scope Changes check ✅ Passed All changes are directly related to the font bundling objective: adding @fontsource-variable/inter dependency, updating Tailwind config, importing the font in application files, and removing Google Fonts links from email templates.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@caillou
Copy link
Copy Markdown
Contributor Author

caillou commented Feb 20, 2026

This PR is kind of messy. I had to add the className={inter.variable} on both:

  • the <Html> in _document.tsx.
  • a wrapper <div> in _app.tsx.

I have only ever worked in Next.js using the app-router. So maybe I am missing something here.

I kind of wonder, if things might be easier if we'd update to Tailwind 4 before attacking this particular issue.

Would it make sense for me to do the following before continuing with this PR:

  • Create an issue to update to update to tailwind 4.
  • Start a separate PR, in which I update to tailwind 4.
  • Once merged, revisit this issue.

@M0NsTeRRR
Copy link
Copy Markdown
Member

Hi,

Thanks for the PR it’s a great enhancement!
It might make sense to tackle Tailwind v4 first, since it’s a bigger task than this one. But doing it the other way around is fine with me too.

@caillou
Copy link
Copy Markdown
Contributor Author

caillou commented Feb 21, 2026

@M0NsTeRRR I will try to push through Tailwind v4 in the coming days.

In the meantime, I have a question with regarding the usage of Google fonts in our mail templates.

It is used in the following templates:

ag fonts.googleapis.com
server/templates/email/generatedpassword/html.pug
8:  link(href='https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap' rel='stylesheet' media='screen')

server/templates/email/media-issue/html.pug
8:  link(href='https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap' rel='stylesheet' media='screen')

server/templates/email/media-request/html.pug
8:  link(href='https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap' rel='stylesheet' media='screen')

server/templates/email/test-email/html.pug
8:  link(href='https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap' rel='stylesheet' media='screen')

server/templates/email/resetpassword/html.pug
8:  link(href='https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap' rel='stylesheet' media='screen')

I have the feeling, we should completely remove the fonts from mail templates and use some good fallback fonts, that might be pre-installed on the (web) mail-clients.

WDYT?

Should I make a separate ticket and PR for this?

@gauthier-th
Copy link
Copy Markdown
Member

@M0NsTeRRR I will try to push through Tailwind v4 in the coming days.

In the meantime, I have a question with regarding the usage of Google fonts in our mail templates.

It is used in the following templates:

ag fonts.googleapis.com
server/templates/email/generatedpassword/html.pug
8:  link(href='https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap' rel='stylesheet' media='screen')

server/templates/email/media-issue/html.pug
8:  link(href='https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap' rel='stylesheet' media='screen')

server/templates/email/media-request/html.pug
8:  link(href='https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap' rel='stylesheet' media='screen')

server/templates/email/test-email/html.pug
8:  link(href='https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap' rel='stylesheet' media='screen')

server/templates/email/resetpassword/html.pug
8:  link(href='https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap' rel='stylesheet' media='screen')

I have the feeling, we should completely remove the fonts from mail templates and use some good fallback fonts, that might be pre-installed on the (web) mail-clients.

WDYT?

Should I make a separate ticket and PR for this?

Tailwind has some good defaults for the fallback fonts (see here), maybe we could use the same ones?

@caillou
Copy link
Copy Markdown
Contributor Author

caillou commented Feb 23, 2026

Removed Google fonts from mail templates. Most probably, these were not used in most mail clients anyway.

Screenshot 2026-02-23 at 15 41 33

@caillou caillou marked this pull request as ready for review February 23, 2026 14:45
@caillou caillou requested a review from a team as a code owner February 23, 2026 14:45
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tailwind.config.js`:
- Around line 18-20: The sans font stack is incorrectly falling back to
defaultTheme.fontFamily.serif; update the tailwind config so the sans key uses
defaultTheme.fontFamily.sans instead of .serif. Locate the fontFamily object
(fontFamily, sans) in tailwind.config.js and replace
defaultTheme.fontFamily.serif with defaultTheme.fontFamily.sans so Inter
Variable correctly falls back to sans fonts.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3a42f59 and 9ad6c61.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (9)
  • package.json
  • server/templates/email/generatedpassword/html.pug
  • server/templates/email/media-issue/html.pug
  • server/templates/email/media-request/html.pug
  • server/templates/email/resetpassword/html.pug
  • server/templates/email/test-email/html.pug
  • src/pages/_app.tsx
  • src/pages/_document.tsx
  • tailwind.config.js

Comment thread tailwind.config.js
Comment thread src/pages/_document.tsx Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements self-hosted fonts to improve user privacy by removing dependencies on Google's font services. The implementation uses the @fontsource-variable/inter package to bundle the Inter Variable font locally, which is then served directly by the application instead of loading from Google Fonts.

Changes:

  • Added @fontsource-variable/inter package dependency for self-hosted Inter font
  • Updated Tailwind configuration to use 'Inter Variable' font family
  • Removed Google Fonts links from HTML document and email templates
  • Enhanced email template font stacks with comprehensive system font fallbacks

Reviewed changes

Copilot reviewed 8 out of 10 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
package.json Added @fontsource-variable/inter version 5.2.8 as a dependency
pnpm-lock.yaml Updated lock file with new font package and its resolution
src/pages/_app.tsx Imported the self-hosted variable font CSS
src/pages/_document.tsx Removed Google Fonts preconnect and stylesheet links
tailwind.config.js Updated font family from 'Inter' to 'Inter Variable'
server/templates/email/test-email/html.pug Removed Google Fonts link and expanded font fallback stack
server/templates/email/resetpassword/html.pug Removed Google Fonts link and expanded font fallback stack
server/templates/email/media-request/html.pug Removed Google Fonts link and expanded font fallback stack
server/templates/email/media-issue/html.pug Removed Google Fonts link and expanded font fallback stack
server/templates/email/generatedpassword/html.pug Removed Google Fonts link and expanded font fallback stack
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/pages/_app.tsx
@caillou caillou requested a review from gauthier-th February 24, 2026 12:33
Copy link
Copy Markdown
Member

@M0NsTeRRR M0NsTeRRR left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Off-topic for this PR, but it would be nice to also avoid the HTTP call to Google in /server/utils/customProxyAgent.ts#113.

@caillou
Copy link
Copy Markdown
Contributor Author

caillou commented Feb 24, 2026

@M0NsTeRRR I'll make a separate ticket and PR for /server/utils/customProxyAgent.ts#113. I'll tackle it later tonight or tomorrow.

@caillou
Copy link
Copy Markdown
Contributor Author

caillou commented Feb 26, 2026

@gauthier-th could we get this merged in?

I'd like to rebase the v3 -> v4 branch and see if there is a better way to actually load the font.

@gauthier-th gauthier-th merged commit 10ea21b into seerr-team:develop Feb 27, 2026
14 checks passed
@cypress
Copy link
Copy Markdown

cypress Bot commented Feb 27, 2026

seerr    Run #3239

Run Properties:  status check passed Passed #3239  •  git commit 10ea21b20f: feat: self-host font for better privacy (#2540)
Project seerr
Branch Review develop
Run status status check passed Passed #3239
Run duration 02m 18s
Commit git commit 10ea21b20f: feat: self-host font for better privacy (#2540)
Committer Pierre Spring
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 31
View all changes introduced in this branch ↗︎

@caillou caillou deleted the 2438-bundle-fonts branch February 27, 2026 15:57
alexlebens pushed a commit to alexlebens/infrastructure that referenced this pull request Feb 27, 2026
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [ghcr.io/seerr-team/seerr](https://github.com/seerr-team/seerr) | minor | `v3.0.1` → `v3.1.0` |
| [seerr-team/seerr](https://github.com/seerr-team/seerr) | minor | `v3.0.1` → `v3.1.0` |

---

### Release Notes

<details>
<summary>seerr-team/seerr (ghcr.io/seerr-team/seerr)</summary>

### [`v3.1.0`](https://github.com/seerr-team/seerr/releases/tag/v3.1.0)

[Compare Source](seerr-team/seerr@v3.0.1...v3.1.0)

##### 🛡️ Security

- Patch [CVE-2026-27707](GHSA-rc4w-7m3r-c2f7)  - Unauthenticated account registration on Plex-configured Seerr instances via Jellyfin authentication endpoint  - ([4ae2068](seerr-team/seerr@4ae2068))
- Patch [CVE-2026-27793](GHSA-f7xw-jcqr-57hp) - Broken Object-Level Authorization in User Profile Endpoint Exposes Third-Party Notification Credentials - ([4f089b2](seerr-team/seerr@4f089b2))
- Patch [CVE-2026-27792](GHSA-gx3h-3jg5-q65f)  - Missing authentication on pushSubscription endpoints  - ([946bdecec](seerr-team/seerr@946bdec))

##### 🚀 Features

- *(helm)* Use an existing PVC as config volume ([#&#8203;2447](seerr-team/seerr#2447)) - ([8f0c904](seerr-team/seerr@8f0c904))
- *(servarr-api)* Make Servarr API request timeout configurable ([#&#8203;2556](seerr-team/seerr#2556)) - ([3bcb4da](seerr-team/seerr@3bcb4da))
- Self-host font for better privacy ([#&#8203;2540](seerr-team/seerr#2540)) - ([10ea21b](seerr-team/seerr@10ea21b))

##### 🐛 Bug Fixes

- *(helm)* Add "v" as prefix for appVersion tag ([#&#8203;2445](seerr-team/seerr#2445)) - ([04b9d87](seerr-team/seerr@04b9d87))
- *(jellyfin-scanner)* Include unmatched seasons in processable seasons ([#&#8203;2538](seerr-team/seerr#2538)) - ([68f56d2](seerr-team/seerr@68f56d2))
- *(link-account)* Fix error-message override ([#&#8203;2547](seerr-team/seerr#2547)) - ([b843be0](seerr-team/seerr@b843be0))
- *(plex-scanner)* Add TVDb to TMDB fallback in plex scanner ([#&#8203;2537](seerr-team/seerr#2537)) - ([7c60a5c](seerr-team/seerr@7c60a5c))
- *(radarr)* Trigger search for existing monitored movies without files ([#&#8203;2391](seerr-team/seerr#2391)) - ([55776ea](seerr-team/seerr@55776ea))
- *(servarr)* Increase default API timeout from 5000ms to 10000ms ([#&#8203;2442](seerr-team/seerr#2442)) - ([b499976](seerr-team/seerr@b499976))
- *(sonarr)* Use configured metadata provider for season filtering ([#&#8203;2516](seerr-team/seerr#2516)) - ([5013d1d](seerr-team/seerr@5013d1d))
- *(watch-data)* Use sentinel values to avoid invalid SQL syntax ([#&#8203;2552](seerr-team/seerr#2552)) - ([947f70c](seerr-team/seerr@947f70c))
- *(watchlist-sync)* Correct permission typo for TV auto requests ([#&#8203;2488](seerr-team/seerr#2488)) - ([e0e4b6f](seerr-team/seerr@e0e4b6f))
- Preserve blocklist on media deletion & optimise watchlist-sync ([#&#8203;2478](seerr-team/seerr#2478)) - ([9da8bb6](seerr-team/seerr@9da8bb6))

##### 🚜 Refactor

- *(tailwind)* Replace deprecated tailwind utilities ([#&#8203;2542](seerr-team/seerr#2542)) - ([f42a4ec](seerr-team/seerr@f42a4ec))

##### 📖 Documentation

- *(synology)* Add installation guide via SynoCommunity ([#&#8203;2503](seerr-team/seerr#2503)) - ([0e636a3](seerr-team/seerr@0e636a3))
- *(truenas)* Update install/migration guide ([#&#8203;2491](seerr-team/seerr#2491)) - ([dc1734d](seerr-team/seerr@dc1734d))
- *(unraid)* Improve unraid migration guide  ([#&#8203;2470](seerr-team/seerr#2470)) - ([5e64d49](seerr-team/seerr@5e64d49))
- Update Unraid install and migration guides with dual permission methods ([#&#8203;2532](seerr-team/seerr#2532)) - ([a0d0eb1](seerr-team/seerr@a0d0eb1))
- Add a warning in migration-guide for third party installation ([#&#8203;2527](seerr-team/seerr#2527)) - ([7e9dff3](seerr-team/seerr@7e9dff3))
- Remove double quotes (") from DB\_HOST environment variable ([#&#8203;2514](seerr-team/seerr#2514)) - ([fa905be](seerr-team/seerr@fa905be))
- Add Unraid installation and migration guide ([#&#8203;2440](seerr-team/seerr#2440)) - ([b6a9132](seerr-team/seerr@b6a9132))
- Fix migration guide title ([#&#8203;2425](seerr-team/seerr#2425)) - ([39ae32f](seerr-team/seerr@39ae32f))

##### ⚡ Performance

- Add missing indexes on all foreign key columns ([#&#8203;2461](seerr-team/seerr#2461)) - ([c6bcfe0](seerr-team/seerr@c6bcfe0))

##### ⚙️ Miscellaneous Tasks

- *(changelog)* Fix changelog template ([#&#8203;2431](seerr-team/seerr#2431)) - ([c2977f6](seerr-team/seerr@c2977f6))
- *(eslint)* Add react/self-closing-comp ([#&#8203;2563](seerr-team/seerr#2563)) - ([cd8b386](seerr-team/seerr@cd8b386))
- *(github)* Add docs and maintenance issue templates ([#&#8203;2467](seerr-team/seerr#2467)) - ([cf4883a](seerr-team/seerr@cf4883a))
- *(helm)* Add GatewayAPI route support to helm chart ([#&#8203;2544](seerr-team/seerr#2544)) - ([3a42f59](seerr-team/seerr@3a42f59))
- *(helm)* Update ghcr.io/seerr-team/seerr ( 3.0.0 → 3.0.1 ) \[skip-ci] ([#&#8203;2441](seerr-team/seerr#2441)) - ([87fb0df](seerr-team/seerr@87fb0df))
- *(husky)* Fixed husky commit message from bash/zsh syntax to sh syntax ([#&#8203;2572](seerr-team/seerr#2572)) - ([a00c9e5](seerr-team/seerr@a00c9e5))
- *(release)* Prepare ${TAG\_VERSION} - ([94a70bb](seerr-team/seerr@94a70bb))
- Updated the Contributing and Security guides to reflect our current practices ([#&#8203;2579](seerr-team/seerr#2579)) - ([0d40a42](seerr-team/seerr@0d40a42))
- Disable nextjs telemetry ([#&#8203;2517](seerr-team/seerr#2517)) - ([cecdd63](seerr-team/seerr@cecdd63))
- Update contributing guide regarding Automated AI Agent ([#&#8203;2518](seerr-team/seerr#2518)) - ([880fbc9](seerr-team/seerr@880fbc9))
- Remove discord notification from release ([#&#8203;2501](seerr-team/seerr#2501)) - ([fba20c1](seerr-team/seerr@fba20c1))
- Add create-tag workflow to streamline release process ([#&#8203;2493](seerr-team/seerr#2493)) - ([06e5eb0](seerr-team/seerr@06e5eb0))
- Update concurrency logic ([#&#8203;2481](seerr-team/seerr#2481)) - ([4939f13](seerr-team/seerr@4939f13))
- Add semantic-pr workflow to enforce conventional commits ([#&#8203;2472](seerr-team/seerr#2472)) - ([5e57fdc](seerr-team/seerr@5e57fdc))

##### New Contributors ❤️

- [@&#8203;caillou](https://github.com/caillou) made their first contribution
- [@&#8203;Kenshin9977](https://github.com/Kenshin9977) made their first contribution
- [@&#8203;MagicLegend](https://github.com/MagicLegend) made their first contribution
- [@&#8203;wiiaam](https://github.com/wiiaam) made their first contribution
- [@&#8203;mjonkus](https://github.com/mjonkus) made their first contribution
- [@&#8203;nova-api](https://github.com/nova-api) made their first contribution
- [@&#8203;mreid-tt](https://github.com/mreid-tt) made their first contribution
- [@&#8203;DataBitz](https://github.com/DataBitz) made their first contribution
- [@&#8203;Hyperion2220](https://github.com/Hyperion2220) made their first contribution
- [@&#8203;blassley](https://github.com/blassley) made their first contribution
- [@&#8203;JanKleine](https://github.com/JanKleine) made their first contribution
- [@&#8203;koiralasandesh](https://github.com/koiralasandesh) made their first contribution<!-- generated by git-cliff -->

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNS43IiwidXBkYXRlZEluVmVyIjoiNDMuMjUuNyIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiaW1hZ2UiXX0=-->

Reviewed-on: https://gitea.alexlebens.dev/alexlebens/infrastructure/pulls/4284
Co-authored-by: Renovate Bot <renovate-bot@alexlebens.net>
Co-committed-by: Renovate Bot <renovate-bot@alexlebens.net>
gwlsn pushed a commit to gwlsn/seerr that referenced this pull request Mar 21, 2026
lucianchauvin pushed a commit to lucianchauvin/jellyseerr that referenced this pull request Apr 20, 2026
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.

Bundle fonts

4 participants