[PR #298] [MERGED] fix: inject default viewport meta (width=device-width, initial-scale=1) #457

Closed
opened 2026-05-06 12:39:53 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/298
Author: @Divkix
Created: 3/6/2026
Status: Merged
Merged: 3/6/2026
Merged by: @james-elicx

Base: mainHead: fix/default-viewport-meta


📝 Commits (3)

  • 0a50fdd fix: inject default viewport meta (width=device-width, initial-scale=1)
  • 4508f9e refactor: export DEFAULT_VIEWPORT and reuse at call sites
  • 71dcd5c refactor: simplify mergeViewport call sites to always apply defaults

📊 Changes

3 files changed (+53 additions, -8 deletions)

View changed files

📝 packages/vinext/src/server/app-dev-server.ts (+4 -7)
📝 packages/vinext/src/shims/metadata.tsx (+6 -1)
📝 tests/features.test.ts (+43 -0)

📄 Description

Fixes #299

Summary

  • mergeViewport() starts from an empty object {}, so when a user exports a viewport config with only themeColor (no width/initialScale), the merged result is truthy but missing viewport dimensions
  • ViewportHead then skips the <meta name="viewport"> tag entirely, breaking mobile rendering for any app that relies on Next.js's implicit viewport defaults
  • Seeds mergeViewport with DEFAULT_VIEWPORT matching Next.js's createDefaultViewport(): { width: "device-width", initialScale: 1 }. User-provided values still override these defaults.

Bug flow (before fix)

User exports: { themeColor: "#000" }
  → mergeViewport returns { themeColor: "#000" } (no width/initialScale)
  → resolvedViewport is NOT null → ?? fallback skipped
  → ViewportHead gets { themeColor: "#000" }
  → parts array is empty → no <meta name="viewport"> tag rendered

Test plan

  • Added mergeViewport unit tests confirming defaults are injected when not provided
  • Added test confirming user-provided values override defaults
  • Added test confirming defaults for empty viewport list
  • Added test confirming later entries override earlier ones while preserving defaults
  • Added integration test confirming ViewportHead renders <meta name="viewport"> when only themeColor is provided
  • All 225 tests pass (bunx vitest run tests/features.test.ts)
  • tsc --noEmit passes

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/cloudflare/vinext/pull/298 **Author:** [@Divkix](https://github.com/Divkix) **Created:** 3/6/2026 **Status:** ✅ Merged **Merged:** 3/6/2026 **Merged by:** [@james-elicx](https://github.com/james-elicx) **Base:** `main` ← **Head:** `fix/default-viewport-meta` --- ### 📝 Commits (3) - [`0a50fdd`](https://github.com/cloudflare/vinext/commit/0a50fddc1519337460be543906c6eca1645a4deb) fix: inject default viewport meta (width=device-width, initial-scale=1) - [`4508f9e`](https://github.com/cloudflare/vinext/commit/4508f9ebe7dadcfd99bc28c3a62470260833c8f3) refactor: export DEFAULT_VIEWPORT and reuse at call sites - [`71dcd5c`](https://github.com/cloudflare/vinext/commit/71dcd5c96dd53ac2dae068fa50338bc140c97788) refactor: simplify mergeViewport call sites to always apply defaults ### 📊 Changes **3 files changed** (+53 additions, -8 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/src/server/app-dev-server.ts` (+4 -7) 📝 `packages/vinext/src/shims/metadata.tsx` (+6 -1) 📝 `tests/features.test.ts` (+43 -0) </details> ### 📄 Description Fixes #299 ## Summary - `mergeViewport()` starts from an empty object `{}`, so when a user exports a viewport config with only `themeColor` (no `width`/`initialScale`), the merged result is truthy but missing viewport dimensions - `ViewportHead` then skips the `<meta name="viewport">` tag entirely, breaking mobile rendering for any app that relies on Next.js's implicit viewport defaults - Seeds `mergeViewport` with `DEFAULT_VIEWPORT` matching Next.js's `createDefaultViewport()`: `{ width: "device-width", initialScale: 1 }`. User-provided values still override these defaults. ### Bug flow (before fix) ``` User exports: { themeColor: "#000" } → mergeViewport returns { themeColor: "#000" } (no width/initialScale) → resolvedViewport is NOT null → ?? fallback skipped → ViewportHead gets { themeColor: "#000" } → parts array is empty → no <meta name="viewport"> tag rendered ``` ## Test plan - [x] Added `mergeViewport` unit tests confirming defaults are injected when not provided - [x] Added test confirming user-provided values override defaults - [x] Added test confirming defaults for empty viewport list - [x] Added test confirming later entries override earlier ones while preserving defaults - [x] Added integration test confirming `ViewportHead` renders `<meta name="viewport">` when only `themeColor` is provided - [x] All 225 tests pass (`bunx vitest run tests/features.test.ts`) - [x] `tsc --noEmit` passes --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 12:39:53 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#457
No description provided.