Skip to content

chore(site): upgrade to Astro 6#946

Merged
decepulis merged 10 commits intomainfrom
chore/astro-6
Apr 6, 2026
Merged

chore(site): upgrade to Astro 6#946
decepulis merged 10 commits intomainfrom
chore/astro-6

Conversation

@decepulis
Copy link
Copy Markdown
Collaborator

@decepulis decepulis commented Mar 13, 2026

Summary

Closes #892

  • Upgrade Astro 5 → 6, along with @astrojs/mdx 4 → 5, @astrojs/netlify 6 → 7, @astrojs/react 4 → 5, Shiki 3 → 4, and @sentry/astro to 10.43.0
  • Fix Zod imports (astro:content/astro:schemaastro/zod) and switch z.record() to z.partialRecord() for enum keys (Zod 4 makes enum-keyed records exhaustive)
  • Replace deprecated z.string().url() with z.url() where applicable
  • Promote experimental.fonts to stable top-level fonts config
  • Remove matchAlgorithm: 'v3' shiki compat (v4 algorithm is the default in Shiki 4)

Not included

  • Remove NETLIFY_DEV=1 workaround — OOM still reproduces with Astro 6 / @astrojs/netlify 7.x. Workaround stays.

Test plan

  • pnpm -F site build passes (content collections validate against Zod 4 schemas)
  • pnpm -F site test — 333 tests pass
  • Heading IDs unchanged — compared heading id attributes between localhost:4321 and videojs.org across docs concept pages (features, ui-components, overview with numbered headings) and blog posts. All identical despite Astro 6's heading ID algorithm change (site uses its own slug generation).
  • Code block syntax highlighting unchanged — compared <pre> tag structure, classes, and inline Shiki color styles between local and prod. Identical output (inline style with --shiki-dark custom properties, not affected by Astro 6's style emission change).
  • Images not affected — site only uses Astro <Image> in 2 places, both with inferSize (no explicit dimensions), so the new crop-to-fit default and no-upscale behavior don't apply.
  • RSS feed (/rss.xml) — valid XML, all blog posts present
  • Sitemap (/sitemap-index.xml) — valid XML in build output with all ~170 URLs
  • Deploy preview — verify SSR routes, OAuth flow, and interactive React islands on Netlify

🤖 Generated with Claude Code


Note

Medium Risk
Framework and integration upgrades (Astro 6, Netlify adapter, MDX, React, Shiki, Sentry) can introduce build/runtime behavior changes affecting rendering and deploy output. Schema validation changes for content collections may also surface new validation failures in CI/builds.

Overview
Upgrades the site app to Astro 6 and bumps related integrations/libraries (notably @astrojs/*, @astrojs/netlify, @astrojs/react, shiki, and @sentry/astro).

Updates content collection schemas and server actions to align with newer Zod/Astro APIs by switching Zod imports to astro/zod, replacing enum-keyed z.record() usage with z.partialRecord(), and moving URL validation to z.url().

Adjusts astro.config.mjs for the new release by promoting experimental.fonts usage to the stable top-level fonts config and removing legacy Shiki compatibility settings.

Reviewed by Cursor Bugbot for commit 7841fa8. Bugbot is set up for automated code reviews on this repo. Configure here.

decepulis and others added 4 commits March 13, 2026 14:26
Upgrade Astro 5 → 6, @astrojs/mdx 4 → 5, @astrojs/netlify 6 → 7,
@astrojs/react 4 → 5, shiki 3 → 4, and @sentry/astro to 10.43.0.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Astro 6 removes `z` from `astro:content` and removes `astro:schema`.
Import from `astro/zod` instead. Also switch `z.record()` to
`z.partialRecord()` for enum keys since Zod 4 makes `z.record()` with
enum keys exhaustive.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Astro 6 stabilizes the fonts API. Move from `experimental.fonts` to
top-level `fonts` config. Also specify all required `devFeatures`
properties for the Netlify adapter.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Shiki 4 uses the v4 match algorithm by default, so the explicit
`matchAlgorithm: 'v3'` option added for backwards compat is no longer
needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 13, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
v10-sandbox Ready Ready Preview, Comment Apr 6, 2026 2:30pm

Request Review

@netlify
Copy link
Copy Markdown

netlify Bot commented Mar 13, 2026

Deploy Preview for vjs10-site ready!

Name Link
🔨 Latest commit 7841fa8
🔍 Latest deploy log https://app.netlify.com/projects/vjs10-site/deploys/69d3c373424bd300086fe442
😎 Deploy Preview https://deploy-preview-946--vjs10-site.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 13, 2026

📦 Bundle Size Report

🎨 @videojs/html — no changes
Presets (7)
Entry Size
/video (default) 25.01 kB
/video (default + hls) 156.97 kB
/video (minimal) 24.98 kB
/video (minimal + hls) 156.92 kB
/audio (default) 23.13 kB
/audio (minimal) 23.17 kB
/background 6.93 kB
Media (7)
Entry Size
/media/background-video 1.04 kB
/media/container 1.59 kB
/media/dash-video 236.26 kB
/media/hls-video 133.40 kB
/media/mux-video 156.10 kB
/media/native-hls-video 3.54 kB
/media/simple-hls-video 15.06 kB
Players (3)
Entry Size
/video/player 6.65 kB
/audio/player 6.63 kB
/background/player 6.63 kB
Skins (17)
Entry Type Size
/video/minimal-skin.css css 3.42 kB
/video/skin.css css 3.44 kB
/video/minimal-skin js 24.98 kB
/video/minimal-skin.tailwind js 25.27 kB
/video/skin js 25.04 kB
/video/skin.tailwind js 25.37 kB
/audio/minimal-skin.css css 2.48 kB
/audio/skin.css css 2.45 kB
/audio/minimal-skin js 23.14 kB
/audio/minimal-skin.tailwind js 23.36 kB
/audio/skin js 23.13 kB
/audio/skin.tailwind js 23.46 kB
/background/skin.css css 117 B
/background/skin js 1.15 kB
/base.css css 157 B
/shared.css css 88 B
/skin-element js 1.34 kB
UI Components (22)
Entry Size
/ui/alert-dialog 2.20 kB
/ui/alert-dialog-close 1.73 kB
/ui/alert-dialog-description 1.62 kB
/ui/alert-dialog-title 1.63 kB
/ui/buffering-indicator 1.91 kB
/ui/captions-button 1.98 kB
/ui/controls 1.97 kB
/ui/error-dialog 2.40 kB
/ui/fullscreen-button 2.00 kB
/ui/mute-button 2.01 kB
/ui/pip-button 1.99 kB
/ui/play-button 1.97 kB
/ui/playback-rate-button 2.00 kB
/ui/popover 2.67 kB
/ui/poster 1.89 kB
/ui/seek-button 2.02 kB
/ui/slider 1.69 kB
/ui/thumbnail 2.28 kB
/ui/time 1.75 kB
/ui/time-slider 2.12 kB
/ui/tooltip 2.53 kB
/ui/volume-slider 2.44 kB

Sizes are marginal over the root entry point.

⚛️ @videojs/react — no changes
Presets (7)
Entry Size
/video (default) 19.99 kB
/video (default + hls) 152.25 kB
/video (minimal) 20.04 kB
/video (minimal + hls) 152.24 kB
/audio (default) 16.84 kB
/audio (minimal) 16.87 kB
/background 3.15 kB
Media (6)
Entry Size
/media/background-video 476 B
/media/dash-video 236.38 kB
/media/hls-video 133.35 kB
/media/mux-video 156.26 kB
/media/native-hls-video 3.50 kB
/media/simple-hls-video 15.03 kB
Skins (14)
Entry Type Size
/video/minimal-skin.css css 3.35 kB
/video/skin.css css 3.37 kB
/video/minimal-skin js 19.95 kB
/video/minimal-skin.tailwind js 23.45 kB
/video/skin js 19.92 kB
/video/skin.tailwind js 23.43 kB
/audio/minimal-skin.css css 2.38 kB
/audio/skin.css css 2.34 kB
/audio/minimal-skin js 16.77 kB
/audio/minimal-skin.tailwind js 19.23 kB
/audio/skin js 16.71 kB
/audio/skin.tailwind js 19.28 kB
/background/skin.css css 90 B
/background/skin js 272 B
UI Components (19)
Entry Size
/ui/alert-dialog 2.01 kB
/ui/buffering-indicator 1.75 kB
/ui/captions-button 1.89 kB
/ui/controls 1.69 kB
/ui/error-dialog 2.15 kB
/ui/fullscreen-button 1.83 kB
/ui/mute-button 1.84 kB
/ui/pip-button 1.88 kB
/ui/play-button 1.83 kB
/ui/playback-rate-button 1.91 kB
/ui/popover 3.43 kB
/ui/poster 1.56 kB
/ui/seek-button 1.88 kB
/ui/slider 3.66 kB
/ui/thumbnail 1.87 kB
/ui/time 1.94 kB
/ui/time-slider 3.23 kB
/ui/tooltip 2.76 kB
/ui/volume-slider 3.22 kB

Sizes are marginal over the root entry point.

🧩 @videojs/core — no changes
Entries (8)
Entry Size
. 5.29 kB
/dom 9.03 kB
/dom/media/custom-media-element 1.82 kB
/dom/media/dash 235.76 kB
/dom/media/hls 132.94 kB
/dom/media/mux 155.60 kB
/dom/media/native-hls 2.90 kB
/dom/media/simple-hls 14.45 kB
🏷️ @videojs/element — no changes
Entries (2)
Entry Size
. 999 B
/context 943 B
📦 @videojs/store — no changes
Entries (3)
Entry Size
. 1.39 kB
/html 696 B
/react 360 B
🔧 @videojs/utils — no changes
Entries (10)
Entry Size
/array 104 B
/dom 1.53 kB
/events 319 B
/function 327 B
/object 247 B
/predicate 265 B
/string 148 B
/style 190 B
/time 478 B
/number 158 B
📦 @videojs/spf — no changes
Entries (3)
Entry Size
. 40 B
/dom 12.45 kB
/playback-engine 12.41 kB

ℹ️ How to interpret

All sizes are standalone totals (minified + brotli).

Icon Meaning
No change
🔺 Increased ≤ 10%
🔴 Increased > 10%
🔽 Decreased
🆕 New (no baseline)

Run pnpm size locally to check current sizes.

decepulis and others added 2 commits March 17, 2026 10:05
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Zod 4 deprecates z.string().url() in favor of z.url(). In the classic
API (which astro/zod re-exports), z.url() still returns a string, so
this is a 1:1 replacement with no downstream type changes.

Also normalizes canonicalURL in Base.astro to always be a string by
appending .href to the URL fallback.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@decepulis
Copy link
Copy Markdown
Collaborator Author

import.meta.env inlining check (Astro 6)

Netlify flagged that Astro 6 always inlines import.meta.env at build time, which can leak secrets into the server bundle if they were previously read at runtime via import.meta.env.

Audited all env var usage in site/ — no issues found:

  • Secrets (OAUTH_*, SESSION_COOKIE_PASSWORD, MUX_*): All use astro:env/server with access: 'secret' — Astro's official runtime-safe mechanism, unaffected by this change.
  • import.meta.env.PROD/DEV/BASE_URL: Vite built-in constants, always inlined — no behavior change.
  • import.meta.env.CONTEXT/COMMIT_REF/DEPLOY_ID (in sentry.server.config.ts): Non-secret Netlify build vars with fallbacks — safe to inline.
  • process.env usage in astro.config.mjs: Config runs at build time anyway — unaffected.

The sandbox package uses vite 8, and pnpm was resolving the site's
vite plugins (@tailwindcss/vite, @vitejs/plugin-react, vite-plugin-svgr)
against it instead of astro's bundled vite 7. This caused peer dependency
warnings and two different vite versions running in the same package.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@decepulis decepulis marked this pull request as ready for review April 6, 2026 14:46
@decepulis decepulis merged commit 266ab70 into main Apr 6, 2026
20 checks passed
@decepulis decepulis deleted the chore/astro-6 branch April 6, 2026 14:46
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.

chore(site): upgrade to Astro 6

1 participant