-
Notifications
You must be signed in to change notification settings - Fork 32
Expand file tree
/
Copy pathnetlify.toml
More file actions
156 lines (131 loc) · 5.32 KB
/
netlify.toml
File metadata and controls
156 lines (131 loc) · 5.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# Netlify configuration for KubeStellar Console
# Enables PR preview deployments with mock data (no backend required)
[build]
# Frontend is in web/ subdirectory
base = "web"
command = "npm ci && npm run build"
publish = "dist"
[functions]
# Netlify Functions directory (relative to base)
directory = "netlify/functions"
node_bundler = "esbuild"
# Edge Functions — inject SEO meta tags, serve robots.txt + sitemap.xml
# These only run on Netlify, not on localhost or cluster deployments
[[edge_functions]]
path = "/*"
function = "seo-meta"
[[edge_functions]]
path = "/robots.txt"
function = "robots"
[[edge_functions]]
path = "/sitemap.xml"
function = "sitemap"
[build.environment]
# Enable demo mode with mock data for Netlify previews
VITE_DEMO_MODE = "true"
NODE_VERSION = "20"
# Nightly E2E status API — proxy to Netlify Function
# Serves live GitHub Actions data (GITHUB_TOKEN set in Netlify dashboard)
[[redirects]]
from = "/api/nightly-e2e/runs"
to = "/.netlify/functions/nightly-e2e"
status = 200
[[redirects]]
from = "/api/public/nightly-e2e/runs"
to = "/.netlify/functions/nightly-e2e"
status = 200
# Presence tracking API — proxy to Netlify Function
[[redirects]]
from = "/api/active-users"
to = "/.netlify/functions/presence"
status = 200
# Missions API — proxy to Netlify Function (console-kb knowledge base)
[[redirects]]
from = "/api/missions/file"
to = "/.netlify/functions/missions-file"
status = 200
[[redirects]]
from = "/api/missions/browse"
to = "/.netlify/functions/missions-browse"
status = 200
# GA4 gtag.js proxy — Netlify Function serves gtag.js from same origin,
# bypassing domain-based ad blockers. This is the Netlify equivalent of
# the Go backend's GA4ScriptProxy. Route handled by gtag-proxy.mts via
# Config.path, so no redirect needed here.
# GA4 event collection — custom lightweight tracker sends directly to /api/m
# (Netlify Function via Config.path, no gtag.js loaded)
# Analytics dashboard API — proxy to Netlify Function
# Serves live GA4 Data API data (GA4_SERVICE_ACCOUNT_JSON + GA4_PROPERTY_ID in Netlify dashboard)
[[redirects]]
from = "/api/analytics-dashboard"
to = "/.netlify/functions/analytics-dashboard"
status = 200
# YouTube playlist API — proxy to Netlify Function
[[redirects]]
from = "/api/youtube/playlist"
to = "/.netlify/functions/youtube-playlist"
status = 200
# YouTube thumbnail proxy — serves thumbnails through our origin to avoid MSW blocking
[[redirects]]
from = "/api/youtube/thumbnail/*"
to = "/.netlify/functions/youtube-thumbnail"
status = 200
# Analytics dashboard page — serve static HTML
[[redirects]]
from = "/analytics"
to = "/analytics.html"
status = 200
# SPA routing - redirect all routes to index.html (only if file doesn't exist)
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
force = false
# Headers for security and caching.
# Cache-Control: no-cache, no-store is set here for all routes so that SPA paths like
# /clusters (served as index.html via the /* rewrite) are always refetched fresh
# after a deploy. Netlify matches headers against the request path, not the
# served file, so the /*.html rule below does NOT cover /clusters etc.
# The /assets/* rule (below) overrides this with immutable for hashed bundles.
[[headers]]
for = "/*"
[headers.values]
X-Frame-Options = "DENY"
X-Content-Type-Options = "nosniff"
Referrer-Policy = "strict-origin-when-cross-origin"
Strict-Transport-Security = "max-age=31536000; includeSubDomains"
Permissions-Policy = "camera=(), microphone=(), geolocation=()"
X-XSS-Protection = "1; mode=block"
Content-Security-Policy = "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.googletagmanager.com https://analytics.kubestellar.io; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self' https://*.google-analytics.com https://*.googleapis.com https://www.googletagmanager.com https://api.github.com https://api.dicebear.com https://fonts.gstatic.com https://analytics.kubestellar.io https://raw.githubusercontent.com ws://localhost:1 wss:; frame-ancestors 'none'"
Cache-Control = "no-cache, no-store, must-revalidate"
Pragma = "no-cache"
# Versioned JS/CSS assets have content-hashed filenames — safe to cache forever.
# Netlify uses the most specific matching path, so /assets/* takes precedence over /*.
[[headers]]
for = "/assets/*"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"
# HTML files must always revalidate to pick up new chunk references after deploys
[[headers]]
for = "/*.html"
[headers.values]
Cache-Control = "no-cache, no-store, must-revalidate"
Pragma = "no-cache"
[[headers]]
for = "/index.html"
[headers.values]
Cache-Control = "no-cache, no-store, must-revalidate"
Pragma = "no-cache"
# Context-specific settings
[context.production]
# Production builds (main branch) - still use demo mode for now
[context.production.environment]
VITE_DEMO_MODE = "true"
[context.deploy-preview]
# PR preview deployments - always use demo mode
[context.deploy-preview.environment]
VITE_DEMO_MODE = "true"
[context.branch-deploy]
# Branch deploys - use demo mode
[context.branch-deploy.environment]
VITE_DEMO_MODE = "true"