-
Notifications
You must be signed in to change notification settings - Fork 45
Expand file tree
/
Copy pathnetlify.toml
More file actions
53 lines (48 loc) · 2.53 KB
/
Copy pathnetlify.toml
File metadata and controls
53 lines (48 loc) · 2.53 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
# OpenTakeoff — one-click static deploy.
# The app lives in web/ and builds to web/dist/. The only server code is the
# gated schedule-scan function (web/netlify/functions/); it stays dark unless
# GEMINI_API_KEY is set, so a default deploy is still fully static.
[build]
base = "web"
# Stage the on-device voice model (RFC #59) same-origin before the build, so
# push-to-talk dictation is live on the hosted demo (~44 MB, gitignored, not
# fetched by the app at runtime). Tolerant by design: a HuggingFace hiccup at
# deploy time logs and deploys WITHOUT voice rather than failing the whole
# static site — feature-absence, never breakage, exactly as the app degrades.
command = "node scripts/fetch-voice-model.mjs || echo 'voice model fetch failed — deploying without voice'; npm run build"
publish = "dist"
# Serverless functions live under the build base (web/netlify/functions).
[functions]
directory = "netlify/functions"
node_bundler = "esbuild"
# One canonical host. Netlify is *documented* to 301 the .netlify.app subdomain
# to the primary custom domain on its own, but it was still answering 200 on
# both hosts after the domain was promoted — so this is declared rather than
# assumed. Two hostnames serving identical 200s splits link equity and is the
# duplicate-content case search engines penalise; the canonical tag in
# index.html alone does not stop a crawler indexing the other host.
# force = true is required: without it the rule loses to an existing static
# asset at the same path, which is every path on this site.
# This must stay FIRST — the /* catch-all below would otherwise swallow it.
[[redirects]]
from = "https://opentakeoff.netlify.app/*"
to = "https://opentakeoff.kentucky-ai.com/:splat"
status = 301
force = true
# Gated "Import from scanned schedule" — must precede the SPA catch-all, else
# /* swallows it and the POST returns index.html.
[[redirects]]
from = "/ai/parse-schedule"
to = "/.netlify/functions/parse-schedule"
status = 200
# Single-page app: serve index.html for any path.
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
# Security headers live in web/public/_headers (copied into dist/ at build) —
# the ONE source of truth. Do not add a [[headers]] block here: two CSP
# headers on the same response are each enforced by the browser (an
# intersection), and this block used to lack the Google sign-in origins
# _headers allows, which silently broke sign-in/webfonts via that
# intersection. See web/public/_headers for the full policy + rationale.