Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions deploy/github-supabase-deploy.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# GitHub Pages + Supabase 部署

> ⚠️ **重建前必讀(2026-10-31,SEC-P1-20261031)**:`<owner>.github.io` 是同一帳號所有 GitHub Pages 專案共用的 origin,任何一個 Pages 站的腳本都讀得到這個 origin 的 localStorage,而 Supabase Auth 會把登入 session 存在 localStorage。因此前端在 `*.github.io` 上時會**自動停用 Google 登入**。重建線上服務時,前端改放在獨立網域(例如 Cloudflare Pages 的 `*.pages.dev`,免費),下文的 Authorized JavaScript origins、Site URL 與 `CORS_ORIGINS` 都改填該網域。

正式環境不使用 Render。GitHub Pages 發布前端,Supabase Edge Function 提供 API,Supabase Database 保存資料。

## 架構
Expand Down
11 changes: 8 additions & 3 deletions frontend/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@ const ONLINE_API_RETIRED = !API_BASE;
const ONLINE_API_RETIRED_MESSAGE = "線上 API 已停用,請在本機啟動 FastAPI 練習。";
const SUPABASE_URL = String(import.meta.env.VITE_SUPABASE_URL || "").trim();
const SUPABASE_PUBLISHABLE_KEY = String(import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY || "").trim();
const authClient = SUPABASE_URL && SUPABASE_PUBLISHABLE_KEY
// *.github.io 是同一帳號所有 GitHub Pages 專案共用的 origin,任何一個站的腳本都讀得到這裡的
// localStorage。Supabase 會把登入 session 存在 localStorage,所以在共用 origin 上一律不啟用登入;
// 重建線上服務時,前端要放在獨立網域(見 deploy/github-supabase-deploy.md)。
const SHARED_PAGES_ORIGIN = window.location.hostname.endsWith(".github.io");
const AUTH_DISABLED_ON_SHARED_ORIGIN_MESSAGE = "這個網址與其他 GitHub Pages 網站共用,為保護登入狀態已停用 Google 登入。";
const authClient = SUPABASE_URL && SUPABASE_PUBLISHABLE_KEY && !SHARED_PAGES_ORIGIN
? createClient(SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, {
auth: { autoRefreshToken: true, detectSessionInUrl: true, persistSession: true },
})
Expand Down Expand Up @@ -89,7 +94,7 @@ function AccountMenu({
if (!authClientConfigured) {
return (
<div className="auth-panel auth-panel-unavailable">
<span className="auth-status">Google 登入尚未設定</span>
<span className="auth-status">{SHARED_PAGES_ORIGIN ? AUTH_DISABLED_ON_SHARED_ORIGIN_MESSAGE : "Google 登入尚未設定"}</span>
</div>
);
}
Expand Down Expand Up @@ -664,7 +669,7 @@ function App() {

const handleSignIn = useCallback(async () => {
if (!authClient) {
showBanner("Google 登入尚未設定。", true);
showBanner(SHARED_PAGES_ORIGIN ? AUTH_DISABLED_ON_SHARED_ORIGIN_MESSAGE : "Google 登入尚未設定。", true);
return;
}
setIsSigningIn(true);
Expand Down
7 changes: 6 additions & 1 deletion static/js/learn.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ const API_DOCS_URL = "https://github.com/frobel0520/AI-Agent-Tutorial/tree/main/
const OWN_WEBHOOK_PATH = "/hooks/incoming";
const SUPABASE_URL = String(window.APP_CONFIG?.supabaseUrl || "").trim();
const SUPABASE_PUBLISHABLE_KEY = String(window.APP_CONFIG?.supabasePublishableKey || "").trim();
const authClient = SUPABASE_URL && SUPABASE_PUBLISHABLE_KEY && window.supabase?.createClient
// *.github.io 是同一帳號所有 GitHub Pages 專案共用的 origin,任何一個站的腳本都讀得到這裡的
// localStorage。Supabase 會把登入 session 存在 localStorage,所以在共用 origin 上一律不啟用登入;
// 重建線上服務時,前端要放在獨立網域(見 deploy/github-supabase-deploy.md)。
const SHARED_PAGES_ORIGIN = window.location.hostname.endsWith(".github.io");
const AUTH_DISABLED_ON_SHARED_ORIGIN_MESSAGE = "這個網址與其他 GitHub Pages 網站共用,為保護登入狀態已停用 Google 登入。";
const authClient = SUPABASE_URL && SUPABASE_PUBLISHABLE_KEY && !SHARED_PAGES_ORIGIN && window.supabase?.createClient
? window.supabase.createClient(SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, {
auth: { autoRefreshToken: true, detectSessionInUrl: true, persistSession: true },
})
Expand Down
Loading