시작하기 전에 준비할 것
- Windows 10 또는 11 PC와 인터넷. 화면은 Chrome 기준입니다. Edge, Whale 등 다른 브라우저도 똑같이 됩니다.
- 내가 쓰는 이메일 주소. 계정 세 개를 만드는 데 씁니다. 하나의 이메일로 셋 다 만들 수 있습니다.
- 웹페이지 파일. 이미 만든 것이 있으면 그것을 씁니다. 없으면 이 가이드가 주는 예제 파일을 그대로 복사해 쓰면 됩니다.
- 결제 수단은 필요 없습니다. 세 서비스 모두 무료 플랜으로 이 가이드의 끝까지 갈 수 있습니다. 카드 등록을 요구하는 화면은 나오지 않습니다.
세 가지 도구가 각각 하는 일
- GitHub — 파일 보관소. 내 웹페이지 파일을 인터넷에 보관합니다. 언제 무엇을 고쳤는지 기록이 남고, 실수해도 되돌릴 수 있습니다.
- Vercel — 배포와 주소. GitHub에 있는 파일을 실제 웹사이트로 띄우고 주소를 줍니다. 파일을 고치면 알아서 다시 배포합니다.
- Supabase — 데이터 저장. 방문자가 남긴 글이나 신청 내역처럼 계속 쌓이는 데이터를 저장합니다. 새로고침해도 사라지지 않습니다.
내 PC의 파일 → GitHub 저장소 → Vercel → 인터넷 주소. 방문자의 브라우저 ↔ Supabase 데이터베이스. 파일은 GitHub를 거쳐 Vercel이 배포하고, 데이터는 방문자의 브라우저가 Supabase와 직접 주고받습니다. 그래서 서버를 직접 만들 필요가 없습니다.
1. 계정 세 개 만들기
GitHub를 먼저 만들어야 합니다. Vercel과 Supabase는 GitHub 계정으로 로그인하는 방식을 쓰면 따로 아이디와 비밀번호를 만들지 않아도 되고, 나중 단계에서 연결도 저절로 됩니다.
1-1. GitHub 계정
- 주소창에
github.com/signup을 입력해 엽니다. - Email에 내 이메일 주소를 적습니다.
- Password에 비밀번호를 적습니다. 15자 이상이거나, 8자 이상이면서 숫자와 소문자를 포함해야 합니다.
- Username에 영문 아이디를 적습니다. 이 아이디가 나중에
github.com/아이디주소가 됩니다. 한글과 공백은 쓸 수 없습니다. - Your Country/Region에서 Korea, South를 고릅니다.
- Create account를 누릅니다.
- 이메일로 온 여섯 자리 숫자를 화면에 입력하면 가입이 끝납니다.
[화면] GitHub 가입 github.com/signup 화면. 네 칸을 채우고 Create account를 누릅니다. Copilot Free 체크박스는 그대로 둬도 됩니다. 무료이고, 이 가이드의 진행에는 영향이 없습니다. 원치 않으면 체크를 풀어도 됩니다.
1-2. Vercel 계정
vercel.com/signup을 엽니다.- Continue with GitHub를 누릅니다.
- GitHub 화면이 뜨면 Authorize Vercel을 눌러 허용합니다.
- 이름을 묻는 화면이 나오면 적고 넘어갑니다. 플랜을 고르라고 하면 Hobby(무료)를 고릅니다.
- Secure Your Account with 2FA 화면이 나오면 아래를 보고 고릅니다. 지금 건너뛰어도 가입은 그대로 끝납니다.
[화면] Vercel 가입 vercel.com/signup 화면. Continue with GitHub로 시작하면 뒤가 편합니다.
1-2-1. “Secure Your Account with 2FA” 화면이 나오면
가입은 이미 끝난 상태입니다. 연습용이면 아래 작은 글씨 Skip securing my account를 눌러 넘어갑니다. 남이 쓸 사이트라면 Set Up Authenticator App으로 켜고 마지막에 나오는 복구 코드를 안전한 곳에 보관합니다.
1-3. Supabase 계정
supabase.com/dashboard/sign-up을 엽니다.- Continue with GitHub를 누르고, GitHub 화면에서 허용합니다.
- 조직(Organization) 이름을 물으면 아무 이름이나 적습니다. 본인 이름도 괜찮습니다. 플랜은 Free를 고릅니다.
[화면] Supabase 가입. 여기서도 GitHub 계정으로 로그인합니다. 세 화면 모두 영어입니다. 번역이 필요하면 Chrome에서 화면 아무 곳이나 오른쪽 클릭한 뒤 한국어로 번역을 누르면 됩니다. 다만 번역된 상태에서는 버튼 이름이 이 가이드와 달라 보이므로, 헷갈리면 원문으로 되돌리세요.
- 브라우저 탭 세 개에서
github.com,vercel.com/dashboard,supabase.com/dashboard가 각각 로그인된 상태로 열린다. - 세 화면 어디에서도 로그인이나 가입을 다시 요구하지 않는다.
한 곳이라도 로그인 화면으로 돌아간다면 그 서비스의 가입을 끝내지 못한 것입니다. 다음 단계로 넘어가기 전에 마무리하세요.
2. 올릴 파일 준비하기
배포에는 규칙이 하나 있습니다. 첫 화면이 될 파일의 이름은 반드시 index.html이어야 합니다. 소문자로 정확히 그 이름이어야 하고, 폴더 맨 바깥(최상단)에 있어야 합니다. 이 규칙만 지키면 나머지는 자유입니다.
이미 만든 페이지가 있다면
- 첫 화면 파일 이름을
index.html로 바꿉니다. - 이미지, CSS, JS 같은 딸린 파일은 같은 폴더 구조 그대로 함께 올립니다.
- 파일 이름에 한글, 공백, 괄호가 있으면 영문과 하이픈으로 바꿉니다. 예:
내 사진 (1).png→photo-1.png. 바꾼 뒤에는 HTML 안에서 그 파일을 부르는 부분도 같이 고쳐야 합니다.
없다면 이 예제로 시작하세요
아래 코드가 이 가이드에서 끝까지 쓰는 예제 페이지입니다. 자기소개 한 줄과 방명록이 있는 한 장짜리 페이지이고, 파일은 index.html 하나뿐입니다. 지금은 데이터베이스가 연결되지 않은 상태라 방명록 자리에 안내문이 보이고, 5단계와 6단계를 마치면 실제로 글이 쌓입니다.
<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>내 웹페이지</title>
<style>
:root{ --bg:#f6f7f9; --card:#fff; --ink:#1b2030; --muted:#5b6472; --line:#e6e8ee; --accent:#3f5bd9; }
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--ink);
font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Malgun Gothic",sans-serif;line-height:1.7}
.wrap{max-width:640px;margin:0 auto;padding:56px 20px 80px}
h1{font-size:34px;margin:0 0 8px}
.sub{color:var(--muted);margin:0 0 32px}
.card{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:22px 24px;margin:0 0 20px}
h2{font-size:18px;margin:0 0 14px}
label{display:block;font-size:14px;color:var(--muted);margin:12px 0 6px}
input,textarea{width:100%;padding:11px 13px;border:1px solid var(--line);border-radius:9px;
font:inherit;background:#fff;color:var(--ink)}
textarea{min-height:88px;resize:vertical}
button{margin-top:16px;width:100%;padding:12px;border:0;border-radius:9px;background:var(--accent);
color:#fff;font:inherit;font-weight:700;cursor:pointer}
button:disabled{opacity:.5;cursor:default}
.msg{margin-top:12px;font-size:14px;color:var(--muted);min-height:20px}
.entry{border-top:1px solid var(--line);padding:14px 0}
.entry:first-child{border-top:0}
.entry b{display:block}
.entry time{font-size:12.5px;color:var(--muted)}
.notice{background:#fef4ec;border:1px solid #e2a06a;border-radius:10px;padding:14px 16px;font-size:14.5px}
</style>
</head>
<body>
<div class="wrap">
<h1>안녕하세요, 강동민입니다</h1>
<p class="sub">이 페이지는 GitHub에 올려 Vercel로 배포했습니다.</p>
<section class="card">
<h2>방명록 남기기</h2>
<form id="guestbook-form">
<label for="name">이름</label>
<input id="name" maxlength="20" required placeholder="이름을 적어 주세요">
<label for="message">한마디</label>
<textarea id="message" maxlength="200" required placeholder="하고 싶은 말을 적어 주세요"></textarea>
<button type="submit" id="submit-btn">남기기</button>
</form>
<p class="msg" id="form-msg"></p>
</section>
<section class="card">
<h2>남겨진 글</h2>
<div id="entries"><p class="msg">불러오는 중...</p></div>
</section>
</div>
<!-- Supabase 라이브러리 -->
<script src="https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2"></script>
<script>
// 여기 두 줄만 내 값으로 바꿉니다 (가이드 6단계)
const SUPABASE_URL = "";
const SUPABASE_KEY = "";
const entriesEl = document.getElementById("entries");
const formEl = document.getElementById("guestbook-form");
const msgEl = document.getElementById("form-msg");
const btnEl = document.getElementById("submit-btn");
const connected = SUPABASE_URL !== "" && SUPABASE_KEY !== "";
const db = connected ? supabase.createClient(SUPABASE_URL, SUPABASE_KEY) : null;
if (!connected) {
entriesEl.innerHTML =
'<div class="notice">아직 데이터베이스를 연결하지 않았습니다. ' +
"가이드의 데이터베이스 단계를 마치고 index.html 위쪽 두 줄을 채우면 " +
"여기에 방명록이 쌓입니다.</div>";
btnEl.disabled = true;
} else {
loadEntries();
}
async function loadEntries() {
const { data, error } = await db
.from("guestbook")
.select("*")
.order("created_at", { ascending: false })
.limit(50);
if (error) {
entriesEl.innerHTML = '<p class="msg">불러오지 못했습니다: ' + error.message + "</p>";
return;
}
if (!data.length) {
entriesEl.innerHTML = '<p class="msg">아직 남겨진 글이 없습니다.</p>';
return;
}
entriesEl.innerHTML = data
.map(function (row) {
return (
'<div class="entry"><b>' +
escapeHtml(row.name) +
"</b>" +
escapeHtml(row.message) +
"<time>" +
new Date(row.created_at).toLocaleString("ko-KR") +
"</time></div>"
);
})
.join("");
}
formEl.addEventListener("submit", async function (event) {
event.preventDefault();
btnEl.disabled = true;
msgEl.textContent = "저장하는 중...";
const { error } = await db.from("guestbook").insert({
name: document.getElementById("name").value.trim(),
message: document.getElementById("message").value.trim(),
});
if (error) {
msgEl.textContent = "저장하지 못했습니다: " + error.message;
} else {
msgEl.textContent = "남겼습니다.";
formEl.reset();
loadEntries();
}
btnEl.disabled = false;
});
function escapeHtml(text) {
return String(text).replace(/[&<>"']/g, function (ch) {
return { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }[ch];
});
}
</script>
</body>
</html>
파일 만드는 법 (메모장으로 충분합니다)
- 바탕화면에서 오른쪽 클릭 후 새로 만들기 > 폴더를 눌러
my-webpage라는 폴더를 만듭니다. - 그 폴더 안에서 오른쪽 클릭 후 새로 만들기 > 텍스트 문서를 만듭니다.
- 메모장으로 열고 위 코드를 붙여 넣습니다.
- 파일 > 다른 이름으로 저장을 누릅니다. 파일 이름에
index.html, 파일 형식은 모든 파일, 인코딩은 UTF-8로 맞추고 저장합니다. - 저장한
index.html을 더블클릭하면 브라우저에서 내 페이지가 열립니다.
index.html.txt가 됩니다. 겉보기에는 index.html처럼 보이는데 배포하면 화면이 안 뜹니다.[화면] 예제 페이지를 브라우저에서 연 모습. 아래쪽 주황색 안내문은 아직 데이터베이스를 연결하지 않았다는 뜻이며, 6단계를 마치면 방명록 목록으로 바뀝니다. 지금 보이는 주소는 file:///C:/Users/...일 것입니다. 이것은 인터넷 주소가 아니라 내 컴퓨터 안의 파일 경로입니다. 이 주소를 다른 사람에게 보내면 열리지 않습니다. 진짜 주소는 4단계에서 받습니다.
- 폴더 안에
index.html이 있고, 파일 확장명을 켠 상태에서 이름이 정확히 그렇게 보인다(index.html.txt가 아니다). - 더블클릭하면 브라우저에서 페이지가 열리고, 한글이 깨지지 않는다.
3. GitHub에 파일 올리기
GitHub에 저장소(repository)를 하나 만들고, 그 안에 파일을 끌어다 놓습니다. 프로그램을 설치할 필요도, 명령어를 칠 필요도 없습니다.
3-1. 저장소 만들기
- 로그인한 상태로
github.com/new를 엽니다. - Repository name에 영문 이름을 적습니다. 예:
my-webpage. 공백 대신 하이픈을 씁니다. - Choose visibility에서 Private를 고릅니다. 비공개로 두어도 Vercel 배포는 문제없이 됩니다. 소스를 공개하고 싶으면 Public을 골라도 됩니다.
- 아래의 Add README, Add .gitignore, Add license는 모두 그대로 둡니다.
- 맨 아래 Create repository를 누릅니다.
[화면] github.com/new. 저장소 이름과 공개 범위만 정하면 됩니다. 나머지는 기본값 그대로 둡니다.
3-2. 파일 올리기
저장소를 만들면 아직 비어 있는 화면이 나옵니다. 가운데 파란 상자 안의 uploading an existing file을 누릅니다.
- 파일 탐색기에서
index.html을 포함한 파일들을 선택해 브라우저의 점선 상자 안으로 끌어다 놓습니다. 마우스로 끌어 놓는 대신 choose your files를 눌러 골라도 됩니다. - 하위 폴더(예:
images)가 있으면 폴더째로 끌어다 놓으면 구조가 유지됩니다. - 아래 Commit changes 칸에는 아무 설명이나 적어도 되고, 비워 두면 자동으로 채워집니다.
- 초록색 Commit changes 버튼을 누릅니다.
[화면] 점선 영역에 파일을 끌어다 놓고, 아래 Commit changes를 누릅니다.
3-3. 잘 올라갔는지 확인
저장소 첫 화면으로 돌아오면 파일 목록이 보입니다. index.html이 목록 맨 바깥에 있는지 꼭 확인하세요. 폴더 안에 들어가 있으면 다음 단계에서 페이지가 안 뜹니다.
- 저장소 첫 화면의 파일 목록에
index.html이 바로 보인다(폴더를 열고 들어가지 않아도 된다). - 파일 이름을 누르면 내가 쓴 코드 내용이 그대로 보인다.
- 화면 위쪽에
1 Commit처럼 커밋 기록이 하나 이상 있다.
4. Vercel로 배포하기
이제 GitHub에 있는 파일을 실제 웹사이트로 띄웁니다. 여기까지 하면 누구나 접속할 수 있는 주소가 생깁니다.
4-1. 저장소 가져오기
- 로그인한 상태로
vercel.com/new를 엽니다. - Import Git Repository 목록에서 방금 만든 저장소(
my-webpage)를 찾아 오른쪽 Import를 누릅니다.
목록에 내 저장소가 안 보인다면 Vercel에게 그 저장소를 볼 권한이 없는 것입니다. 목록 아래의 Adjust GitHub App Permissions(또는 계정 선택 옆의 설정 링크)를 눌러 All repositories를 허용하거나, 해당 저장소를 골라 추가한 뒤 돌아오면 나타납니다.
4-2. 설정 확인하고 배포
- Project Name은 그대로 두어도 됩니다. 이 이름이 주소의 앞부분이 됩니다.
- Application Preset(또는 Framework Preset)이 Other인지 확인합니다. HTML 파일만 있는 페이지는 Other가 맞습니다.
- Root Directory는
./그대로 둡니다. 단, GitHub에서 파일이 폴더 안에 들어가 있다면 Edit를 눌러 그 폴더를 골라야 합니다. - Build and Output Settings와 Environment Variables는 건드리지 않습니다.
- Deploy를 누릅니다.
[화면] 프리셋이 Other인지만 보고 Deploy를 누릅니다.
4-3. 주소 확인
보통 10초에서 1분 사이에 배포가 끝나고 Congratulations! 화면이 나옵니다. 가운데 미리보기에 내 페이지가 그대로 보이면 성공입니다.
미리보기 이미지나 아래쪽 Continue to Dashboard를 누르면 프로젝트 화면으로 갑니다. 여기서 Domains 아래 주소가 내 웹사이트 주소입니다. 보통 프로젝트이름.vercel.app 형태입니다.
[화면] 상태가 Ready가 되면 배포가 끝난 것입니다. 강조한 주소가 내 사이트 주소이고, 오른쪽 위 Visit으로 바로 열 수 있습니다.
주소를 휴대폰으로도 열어 보세요. 진짜 인터넷에 올라간 것이라 다른 기기, 다른 사람도 그대로 볼 수 있습니다. 여기까지가 “배포”의 전부입니다. 이제부터는 GitHub만 고치면 됩니다. GitHub의 파일을 바꾸면 Vercel이 그 변화를 감지해 자동으로 다시 배포합니다.
- Vercel 프로젝트 화면의 Status가 Ready다.
- Domains의 짧은 주소를 브라우저 주소창에 붙여 넣으면 내 페이지가 열린다.
- 휴대폰(또는 다른 사람의 기기)에서도 같은 주소가 열린다.
데이터를 받을 일이 없는 페이지라면 여기서 끝내도 됩니다. 방명록, 신청서, 문의처럼 방문자 입력을 저장해야 한다면 5단계로 이어집니다.
5. Supabase에 표 만들기
지금 페이지는 글을 남겨도 저장할 곳이 없습니다. Supabase에 표(table)를 하나 만들어 그 자리를 마련합니다. 엑셀 시트를 하나 만든다고 생각하면 됩니다.
이미 만든 내 페이지를 쓰고 있다면 여기부터는 그 페이지에 방명록 같은 입력 기능이 있어야 의미가 있습니다. 없다면 2단계의 예제 코드에서 <form>부터 </script>까지를 통째로 복사해 내 페이지에 붙여 넣으면 같은 방명록이 생깁니다. 붙여 넣을 위치는 </body> 바로 위입니다.
5-1. 프로젝트 만들기
supabase.com/dashboard를 열고 New project를 누릅니다.- Project name에 영문 이름을 적습니다. 예:
my-webpage. - Database Password는 Generate a password를 눌러 만들고, 따로 적어 둡니다. 이 가이드에서는 쓰지 않지만 나중에 필요할 때 다시 볼 수 없습니다.
- Region은 Northeast Asia (Seoul)을 고릅니다. 한국에서 접속할 때 가장 빠릅니다.
- 아래 Security의 체크박스 세 개는 기본값 그대로 둡니다. 위의 두 개가 켜져 있어야 브라우저가 데이터베이스와 대화할 수 있습니다.
- Create new project를 누르고 1분에서 2분 정도 기다립니다.
[화면] 채울 것은 사실상 이름과 리전 둘뿐입니다. 비밀번호는 Generate a password로 만들고 따로 적어 둡니다. GitHub 연결은 건너뛰어도 됩니다.
준비가 끝나면 제목 아래에 https://...supabase.co 형태의 주소가 보이면 완성입니다. 이 주소는 6단계에서 씁니다. 무료 플랜은 프로젝트를 2개까지 활성 상태로 둘 수 있습니다. 이미 두 개가 있으면 새로 만들 수 없다는 안내가 나옵니다.
5-2. SQL Editor 열기
- 화면 맨 왼쪽 끝을 봅니다. 아이콘만 세로로 늘어선 좁은 띠가 있습니다.
- 그 띠에 마우스를 올리면 폭이 넓어지면서 이름이 나타납니다. 위에서부터 Project Overview, Table Editor, SQL Editor, Database, Authentication, Storage 순입니다.
- 위에서 세 번째 SQL Editor를 누릅니다. 아이콘은
>_모양입니다. 키보드로는 G를 누르고 이어서 S를 눌러도 같은 화면으로 갑니다. - 빈 편집기가 열립니다. 가운데 넓은 칸에
Hit CTRL+SHIFT+K to generate query or just start typing이라는 흐린 안내가 있고, 오른쪽 위에 초록색 Run 버튼이 있습니다.
왼쪽 띠가 안 보인다면 화면 왼쪽 아래 구석의 작은 사각형 아이콘을 누르면 메뉴가 접히고 펴집니다.
5-3. SQL 한 번 붙여 넣기
표를 만들고, 누가 읽고 쓸 수 있는지까지 한 번에 정합니다. 방금 연 SQL Editor의 빈 칸에 아래 코드를 전부 붙여 넣고 오른쪽 위 Run을 누릅니다. 아래 Results 칸에 Success. No rows returned가 뜨면 성공입니다.
create table guestbook (
id bigint generated always as identity primary key,
name text not null,
message text not null,
created_at timestamptz not null default now()
);
alter table guestbook enable row level security;
create policy "누구나 읽기" on guestbook
for select to anon using (true);
create policy "누구나 쓰기" on guestbook
for insert to anon with check (true);
[화면] 코드를 붙여 넣고 오른쪽 위 Run을 누릅니다. 아래에 Success. No rows returned가 나오면 성공입니다.
5-4. 확인
왼쪽 아이콘 띠에서 네 번째 Database를 누르면 가운데에 하위 목록이 생기는데, 그중 Policies를 누릅니다. guestbook 표 아래에 정책 두 개가 보이면 제대로 된 것입니다. 같은 띠의 두 번째 Table Editor로 가면 방금 만든 표가 목록에 보입니다.
6. 주소와 키를 페이지에 넣기
마지막으로 내 페이지에게 “데이터는 여기에 저장해”라고 알려 줍니다. 값 두 개만 넣으면 됩니다.
6-1. 값 두 개 복사하기
- Project URL: 5단계 화면 위쪽에 있는
https://...supabase.co주소입니다. Copy를 눌러 복사합니다. - Publishable key: 왼쪽 아래 톱니바퀴(Project Settings) > API Keys로 갑니다. Publishable key 칸의
sb_publishable_...로 시작하는 값을 복사 아이콘으로 복사합니다.
anon과 service_role이라고 불렀습니다.6-2. index.html에 붙여 넣기
- GitHub 저장소에서
index.html을 누릅니다. - 파일 내용 오른쪽 위의 연필 아이콘을 눌러 편집 화면을 엽니다.
- 편집 화면 안을 한 번 클릭한 뒤 Ctrl + F를 누르고
SUPABASE_URL을 입력하면 해당 줄로 바로 이동합니다.
고치기 전
const SUPABASE_URL = "";
const SUPABASE_KEY = "";
고친 뒤 (값은 각자 자기 것으로)
const SUPABASE_URL = "https://abcdefghijklmnop.supabase.co";
const SUPABASE_KEY = "sb_publishable_XXXXXXXXXXXXXXXXXXXXXX";
- 따옴표
"는 지우지 말고 그 안에만 붙여 넣습니다. - 줄 끝의 세미콜론
;도 그대로 둡니다. - 주소 끝에
/가 붙어 있으면 지웁니다.
다 고쳤으면 오른쪽 위 Commit changes...를 누릅니다. 창이 하나 뜨는데, 설명은 비워 두어도 되고 Commit directly to the main branch가 선택된 그대로 두면 됩니다. 초록색 Commit changes를 눌러 저장합니다.
내 PC에 작업용 원본을 두고 앞으로도 거기서 고쳐 나갈 사람은, 내 PC의 index.html에 두 줄을 채운 뒤 Add file > Upload files로 덮어쓰는 편이 낫습니다.
6-3. 자동 재배포 확인
저장하는 순간 Vercel이 알아서 다시 배포합니다. Vercel 프로젝트의 Deployments 화면에 새 줄이 하나 생기고, 상태가 Ready로 바뀌면 끝입니다. 보통 1분 안에 끝납니다.
화면이 그대로여도 당황하지 마세요. 브라우저가 이전 파일을 기억하고 있을 수 있습니다. Ctrl + Shift + R을 눌러 강력 새로고침하면 최신 파일로 다시 받아옵니다.
이제 내 주소로 접속해 이름과 한마디를 적고 남기기를 눌러 보세요. 주황색 안내문이 사라지고 남긴 글이 아래 목록에 나타납니다.
- 배포된 주소에서 남기기 버튼이 눌린다(회색으로 비활성화돼 있지 않다).
- 글을 남기면 “남겼습니다.”라는 문구가 뜨고, 아래 목록에 방금 쓴 글이 나타난다.
- 페이지를 새로고침해도 그 글이 그대로 있다.
7. 확인하고 마무리하기
7-1. 저장이 실제로 됐는지 확인
Supabase의 Table Editor에서 왼쪽 목록의 guestbook을 눌러 보세요. 방금 남긴 글이 한 줄씩 들어와 있으면 진짜로 저장된 것입니다. 여기서 이상한 글을 직접 지울 수도 있습니다(줄 왼쪽 체크 후 삭제).
7-2. 앞으로 페이지를 고치는 방법
GitHub에서 파일을 열고 연필 아이콘을 눌러 고친 뒤 Commit changes를 누르면 됩니다. 그때마다 Vercel이 1분 안에 다시 배포합니다. 잘못 고쳤으면 그 파일의 History에서 예전 버전을 열어 되돌립니다.
7-3. 알아 둘 한 가지
Supabase 무료 플랜은 일주일 동안 아무도 안 들어오면 프로젝트를 일시정지합니다. 그러면 방명록만 안 되고 페이지는 그대로 열립니다. 대시보드에서 Restore를 누르면 다시 살아나고 데이터는 지워지지 않습니다.
Windows에서만 겪는 함정
- 확장자가 숨겨져 있습니다. Windows는 기본적으로
.html,.txt같은 확장자를 감춥니다. 그래서index.html.txt가 화면에는index.html로 보입니다. 파일 탐색기에서 보기 > 표시 > 파일 확장명에 체크하면(Windows 10은 보기 탭의 파일 확장명) 진짜 이름이 보입니다. - 대문자와 소문자를 구분하지 않습니다. 내 PC에서는
Style.css와style.css가 같은 파일 취급이라 잘 열립니다. 그런데 배포된 서버는 이 둘을 다른 파일로 봅니다. HTML에 적은 파일 이름과 실제 파일 이름의 대소문자를 글자 하나까지 똑같이 맞추세요. - 메모장 저장 인코딩. 저장할 때 인코딩을 UTF-8로 맞추지 않으면 배포 후 한글이
?나 깨진 글자로 나옵니다. “UTF-8(BOM)”이 아니라 그냥 UTF-8이면 가장 무난합니다.
문제 해결
배포는 됐는데 404 NOT_FOUND가 뜹니다
거의 항상 원인은 셋 중 하나입니다. 첫째, 첫 화면 파일 이름이 index.html이 아닙니다(대문자 Index.html도 안 됩니다). 둘째, index.html이 폴더 안에 들어가 있습니다. 이 경우 Vercel 프로젝트의 Settings > General > Root Directory를 그 폴더로 바꾸면 됩니다. 셋째, 진짜 파일 이름이 index.html.txt입니다.
메모장에서 코드를 붙여 넣었더니 줄이 다 붙어 버립니다
메모장 상단 메뉴에서 서식 > 자동 줄 바꿈을 꺼도 되지만, 화면에 어떻게 보이든 저장되는 내용은 같습니다.
고쳤는데 사이트에 예전 화면이 그대로입니다
순서대로 확인하세요. 1) GitHub에서 실제로 커밋이 됐는지, 2) Vercel의 Deployments에 새 줄이 생겼고 상태가 Ready인지, 3) 브라우저 캐시인지. 셋째라면 Ctrl + Shift + R로 강력 새로고침하거나 시크릿 창에서 열어 보세요.
글을 남기면 “new row violates row-level security policy”가 뜹니다
쓰기 정책이 없다는 뜻입니다. 5단계 SQL에서 create policy "누구나 쓰기" 부분이 실행되지 않았을 가능성이 큽니다. SQL Editor에서 아래 한 덩어리만 다시 실행하세요.
create policy "누구나 쓰기" on guestbook
for insert to anon with check (true);
“Invalid API key”가 뜹니다
키를 복사하다 앞뒤 공백이나 줄바꿈이 섞였거나, 키 일부만 복사된 경우입니다. API Keys 화면의 복사 아이콘을 눌러 다시 복사하고, 따옴표 안에 공백 없이 붙여 넣으세요.
전체 소요 시간 숫자는 원문에 없습니다. [확인 필요]