Production‑ready starter with Firebase Authentication (email/password + Google), secure session cookies, centralized route guards, and a server‑first data approach (no client Firestore). Ships with TailwindCSS, dark/light theme, and a small component library.
src/hooks.server.jsgit clone <this-repo>
cd Sveltekit-Prototyper
npm install
cp env.example .env
# fill in all values in .env (see below)
npm run dev
Visit http://localhost:5173.
Create a .env file (never commit it). Client‑side variables must be prefixed with VITE_.
VITE_FIREBASE_API_KEY=
VITE_FIREBASE_AUTH_DOMAIN=
VITE_FIREBASE_PROJECT_ID=
VITE_FIREBASE_STORAGE_BUCKET=
VITE_FIREBASE_MESSAGING_SENDER_ID=
VITE_FIREBASE_APP_ID=
# Optional but supported by the codebase
VITE_FIREBASE_MEASUREMENT_ID=
You can find these in Firebase Console → Project settings → Your apps → Web app.
These are used only on the server to verify tokens and create session cookies. Keep them secret.
FIREBASE_PROJECT_ID=
FIREBASE_CLIENT_EMAIL=
# If your private key contains newlines, either keep them as real newlines
# or escape them as \n (the code handles both):
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
The Admin credentials come from Firebase Console → Project settings → Service accounts → Generate new private key. Do not expose this key to the client.
npm run dev # start dev server
npm run build # production build
npm run preview # preview production build locally
npm run lint # check formatting and linting
npm run format # format code with Prettier
email/password or Google).POST /api/auth/login.session cookie.users/{uid}) using the Admin SDK.src/hooks.server.js reads the cookie on every request and sets event.locals.user./app; other paths redirect to /app./verify-email./, /login, /account, /reset-password; other paths redirect to /login.Endpoints:
POST /api/auth/login – verifies ID token, creates the session cookie, and upserts the profilePOST /api/auth/logout – clears the session cookie/ landing/login – email/password and Google login/verify-email – prompt to verify address and resend link/reset-password – send reset email/app – protected area after verification/dynamic-routes/[slug] — dynamic pages that can be populated with data+server.js routes or +layout.server.js).users/{uid} so first‑time sign‑ins get a profile document.src/routes/api/... and use adminDb from $lib/server/firebase-admin.Example (server):
// src/routes/api/widgets/+server.js
import { json } from '@sveltejs/kit';
import { adminDb } from '$lib/server/firebase-admin';
export async function GET() {
const snapshot = await adminDb.collection('widgets').get();
return json(snapshot.docs.map((d) => ({ id: d.id, ...d.data() })));
}
signInWithEmailAndPassword, signInWithPopup, sendPasswordResetEmail, sendEmailVerification.Example (dynamic import in a click handler):
<script>
let email = $state('');
let password = $state('');
async function handleLogin() {
const { login } = await import('$lib/firebase/auth');
await login(email, password);
}
</script>
<button onclick={handleLogin}>Log in</button>
tailwind.config.js and styles in src/lib/styles/.src/lib/components/parts/ and src/lib/components/blocks/.Works out of the box on platforms supported by @sveltejs/adapter-auto (Vercel, Netlify, Node, etc.).
VITE_… and server‑only FIREBASE_…).Cookie security is already configured to be secure in production.
FIREBASE_PRIVATE_KEY newlines are correct (see above).session cookie is set after login.