mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
chore(site): move to netlify (#381)
This commit is contained in:
@@ -120,6 +120,9 @@ Pods/
|
||||
# Vercel
|
||||
.vercel
|
||||
|
||||
# Netlify
|
||||
.netlify
|
||||
|
||||
# -------------------------
|
||||
# Package Manager Locks
|
||||
# Keep only one when enforcing workspace consistency
|
||||
|
||||
Generated
+2703
-272
File diff suppressed because it is too large
Load Diff
@@ -3,11 +3,9 @@
|
||||
import process from 'node:process';
|
||||
|
||||
import mdx from '@astrojs/mdx';
|
||||
import netlify from '@astrojs/netlify';
|
||||
import react from '@astrojs/react';
|
||||
import sitemap from '@astrojs/sitemap';
|
||||
|
||||
import vercel from '@astrojs/vercel';
|
||||
|
||||
import sentry from '@sentry/astro';
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
import { defineConfig, fontProviders } from 'astro/config';
|
||||
@@ -25,9 +23,9 @@ const SITE_URL = 'https://v10.videojs.org';
|
||||
export default defineConfig({
|
||||
site: SITE_URL,
|
||||
trailingSlash: 'never',
|
||||
adapter: vercel(),
|
||||
adapter: netlify(),
|
||||
redirects: {
|
||||
// Redirects are configured in vercel.json
|
||||
// Redirects are configured in netlify.toml
|
||||
},
|
||||
integrations: [
|
||||
sentry({
|
||||
|
||||
@@ -37,7 +37,7 @@ const V8_URLS = [
|
||||
'https://videojs.org/blog/the-end-of-html-first/',
|
||||
'https://videojs.org/blog/video-js-5-11-0-prelease/',
|
||||
'https://videojs.org/blog/video-js-5-s-fluid-mode-and-playlist-picker/',
|
||||
'https://videojs.org/blog/video-js-5-the-only-thing-that’s-changed-is-everything-except-for-like-3-things-that-didn-t-including-the-name/',
|
||||
"https://videojs.org/blog/video-js-5-the-only-thing-that's-changed-is-everything-except-for-like-3-things-that-didn-t-including-the-name/",
|
||||
'https://videojs.org/blog/it-s-here-5-0-release-candidates/',
|
||||
'https://videojs.org/blog/video-js-4-12-the-last-of-the-4-minors/',
|
||||
'https://videojs.org/blog/video-js-4-9-now-can-join-the-party/',
|
||||
@@ -178,35 +178,40 @@ interface V8UrlStatus {
|
||||
status: 'migrated' | 'redirected' | 'needs migration';
|
||||
}
|
||||
|
||||
interface VercelRedirect {
|
||||
source: string;
|
||||
destination: string;
|
||||
statusCode?: number;
|
||||
permanent?: boolean;
|
||||
interface NetlifyRedirect {
|
||||
from: string;
|
||||
to: string;
|
||||
status: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a pathname matches a Vercel redirect source pattern
|
||||
* Supports exact matches and :path(.*) wildcard patterns
|
||||
*/
|
||||
function matchesVercelPattern(pathname: string, pattern: string): boolean {
|
||||
// Remove trailing slash for consistent matching
|
||||
function parseNetlifyToml(content: string): NetlifyRedirect[] {
|
||||
const redirects: NetlifyRedirect[] = [];
|
||||
const redirectRegex = /\[\[redirects\]\]\s+from\s*=\s*"([^"]+)"\s+to\s*=\s*"([^"]+)"\s+status\s*=\s*(\d+)/g;
|
||||
|
||||
let match: RegExpExecArray | null;
|
||||
while ((match = redirectRegex.exec(content)) !== null) {
|
||||
redirects.push({
|
||||
from: match[1],
|
||||
to: match[2],
|
||||
status: parseInt(match[3], 10),
|
||||
});
|
||||
}
|
||||
|
||||
return redirects;
|
||||
}
|
||||
|
||||
function matchesNetlifyPattern(pathname: string, pattern: string): boolean {
|
||||
const normalizedPath = pathname.replace(/\/$/, '');
|
||||
const normalizedPattern = pattern.replace(/\/$/, '');
|
||||
|
||||
// Exact match
|
||||
if (normalizedPattern === normalizedPath) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Handle :path(.*) wildcard pattern
|
||||
// Convert /tags/:path(.*) to a regex that matches /tags/anything
|
||||
if (normalizedPattern.includes(':path(')) {
|
||||
const regexPattern = normalizedPattern
|
||||
.replace(/:[^/]+\(\.\*\)/g, '.*') // :path(.*) -> .*
|
||||
.replace(/\//g, '\\/'); // Escape slashes
|
||||
const regex = new RegExp(`^${regexPattern}$`);
|
||||
return regex.test(normalizedPath);
|
||||
// Handle * splat pattern (e.g., /tags/* matches /tags/anything)
|
||||
if (normalizedPattern.endsWith('/*')) {
|
||||
const prefix = normalizedPattern.slice(0, -2);
|
||||
return normalizedPath === prefix || normalizedPath.startsWith(`${prefix}/`);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -220,20 +225,18 @@ export default function checkV8Urls(): AstroIntegration {
|
||||
// Convert URL to file path
|
||||
const buildDir = fileURLToPath(dir);
|
||||
|
||||
// Check for Vercel config files
|
||||
// buildDir is dist/client/, so go up two levels to site/
|
||||
const siteDir = resolve(buildDir, '..', '..');
|
||||
const vercelConfigPath = resolve(siteDir, '.vercel', 'output', 'config.json');
|
||||
const vercelJsonPath = resolve(siteDir, 'vercel.json');
|
||||
// buildDir is dist/, so go up one level to site/
|
||||
const siteDir = resolve(buildDir, '..');
|
||||
const netlifyTomlPath = resolve(siteDir, 'netlify.toml');
|
||||
|
||||
// Read vercel.json redirects if it exists
|
||||
let vercelJsonRedirects: VercelRedirect[] = [];
|
||||
if (existsSync(vercelJsonPath)) {
|
||||
// Read netlify.toml redirects if it exists
|
||||
let netlifyRedirects: NetlifyRedirect[] = [];
|
||||
if (existsSync(netlifyTomlPath)) {
|
||||
try {
|
||||
const vercelJson = JSON.parse(readFileSync(vercelJsonPath, 'utf-8'));
|
||||
vercelJsonRedirects = vercelJson.redirects || [];
|
||||
const content = readFileSync(netlifyTomlPath, 'utf-8');
|
||||
netlifyRedirects = parseNetlifyToml(content);
|
||||
} catch {
|
||||
// Ignore JSON parse errors
|
||||
// Ignore parse errors
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,49 +257,17 @@ export default function checkV8Urls(): AstroIntegration {
|
||||
if (existsSync(htmlPath1) || existsSync(htmlPath2)) {
|
||||
status = 'migrated';
|
||||
} else {
|
||||
// Check for redirects in vercel.json first
|
||||
const hasVercelJsonRedirect = vercelJsonRedirects.some((redirect) => {
|
||||
// Check if redirect has a redirect status code (or permanent flag)
|
||||
const isRedirect = redirect.statusCode
|
||||
? redirect.statusCode >= 301 && redirect.statusCode <= 308
|
||||
: redirect.permanent !== undefined;
|
||||
|
||||
// Check for redirects in netlify.toml
|
||||
const hasNetlifyRedirect = netlifyRedirects.some((redirect) => {
|
||||
const isRedirect = redirect.status >= 301 && redirect.status <= 308;
|
||||
if (isRedirect) {
|
||||
return matchesVercelPattern(pathname, redirect.source);
|
||||
return matchesNetlifyPattern(pathname, redirect.from);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if (hasVercelJsonRedirect) {
|
||||
if (hasNetlifyRedirect) {
|
||||
status = 'redirected';
|
||||
} else {
|
||||
// Fall back to checking .vercel/output/config.json (adapter-generated)
|
||||
if (existsSync(vercelConfigPath)) {
|
||||
try {
|
||||
const vercelConfig = JSON.parse(readFileSync(vercelConfigPath, 'utf-8'));
|
||||
const routes = vercelConfig.routes || [];
|
||||
|
||||
// Check if this pathname has a redirect (status 301/302/307/308)
|
||||
const hasRedirect = routes.some((route: any) => {
|
||||
if (route.status && route.status >= 301 && route.status <= 308) {
|
||||
// Route has a redirect status code
|
||||
const src = route.src;
|
||||
// Match against pathname (src is a regex pattern)
|
||||
// Simple check: convert pathname to regex pattern
|
||||
const pathPattern = `^${pathname.replace(/\/$/, '')}$`;
|
||||
const pathPatternWithSlash = `^${pathname}$`;
|
||||
return src === pathPattern || src === pathPatternWithSlash;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if (hasRedirect) {
|
||||
status = 'redirected';
|
||||
}
|
||||
} catch {
|
||||
// Ignore JSON parse errors
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# Redirect old theme demo pages to home
|
||||
[[redirects]]
|
||||
from = "/city"
|
||||
to = "/"
|
||||
status = 308
|
||||
|
||||
[[redirects]]
|
||||
from = "/fantasy"
|
||||
to = "/"
|
||||
status = 308
|
||||
|
||||
[[redirects]]
|
||||
from = "/forest"
|
||||
to = "/"
|
||||
status = 308
|
||||
|
||||
[[redirects]]
|
||||
from = "/sea"
|
||||
to = "/"
|
||||
status = 308
|
||||
|
||||
# Redirect old tags pages to blog (no tag filtering in v10)
|
||||
[[redirects]]
|
||||
from = "/tags"
|
||||
to = "/blog"
|
||||
status = 307
|
||||
|
||||
[[redirects]]
|
||||
from = "/tags/*"
|
||||
to = "/blog"
|
||||
status = 307
|
||||
+1
-2
@@ -5,7 +5,6 @@
|
||||
"scripts": {
|
||||
"dev": " astro dev",
|
||||
"build": "astro build",
|
||||
"preview": "echo 'Preview server is not supported on with the Vercel adapter.'",
|
||||
"astro": "astro",
|
||||
"test": "vitest run",
|
||||
"test:watch": "vitest",
|
||||
@@ -14,10 +13,10 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/mdx": "^4.3.7",
|
||||
"@astrojs/netlify": "^6.6.4",
|
||||
"@astrojs/react": "^4.4.0",
|
||||
"@astrojs/rss": "^4.0.12",
|
||||
"@astrojs/sitemap": "^3.6.0",
|
||||
"@astrojs/vercel": "^8.2.9",
|
||||
"@base-ui-components/react": "1.0.0-beta.4",
|
||||
"@nanostores/react": "^1.0.0",
|
||||
"@pagefind/default-ui": "^1.4.0",
|
||||
|
||||
@@ -2,9 +2,9 @@ import * as Sentry from '@sentry/astro';
|
||||
|
||||
Sentry.init({
|
||||
dsn: 'https://6bcdfa6b82da6dd4d7753618a9a69c7c@o43841.ingest.us.sentry.io/4510671167160320',
|
||||
environment: import.meta.env.VERCEL_ENV || 'development',
|
||||
environment: import.meta.env.CONTEXT || 'development',
|
||||
enabled: import.meta.env.PROD,
|
||||
release: import.meta.env.VERCEL_GIT_COMMIT_SHA || import.meta.env.VERCEL_DEPLOYMENT_ID || undefined,
|
||||
release: import.meta.env.COMMIT_REF || import.meta.env.DEPLOY_ID || undefined,
|
||||
// Adds request headers and IP for users, for more info visit:
|
||||
// https://docs.sentry.io/platforms/javascript/guides/astro/configuration/options/#sendDefaultPii
|
||||
sendDefaultPii: true,
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"redirects": [
|
||||
{
|
||||
"source": "/city",
|
||||
"destination": "/",
|
||||
"statusCode": 308
|
||||
},
|
||||
{
|
||||
"source": "/fantasy",
|
||||
"destination": "/",
|
||||
"statusCode": 308
|
||||
},
|
||||
{
|
||||
"source": "/forest",
|
||||
"destination": "/",
|
||||
"statusCode": 308
|
||||
},
|
||||
{
|
||||
"source": "/sea",
|
||||
"destination": "/",
|
||||
"statusCode": 308
|
||||
},
|
||||
{
|
||||
"source": "/tags",
|
||||
"destination": "/blog",
|
||||
"statusCode": 307
|
||||
},
|
||||
{
|
||||
"source": "/tags/:path(.*)",
|
||||
"destination": "/blog",
|
||||
"statusCode": 307
|
||||
}
|
||||
]
|
||||
}
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
"tasks": {
|
||||
"build": {
|
||||
"dependsOn": ["^build"],
|
||||
"outputs": ["dist/**", ".vercel/output/**"]
|
||||
"outputs": ["dist/**", ".netlify/**"]
|
||||
},
|
||||
"dev": {
|
||||
"cache": false,
|
||||
|
||||
Reference in New Issue
Block a user