Install with npm
Drop the guestbook into your existing Next.js app.
Check Dependencies
Ensure you have your required dependencies, which Next.js and React should already satisfy:
-
next(App Router only — Pages Router is not supported.) -
reactandreact-dom -
@supabase/supabase-js -
@supabase/ssr(cookie sessions for Google admin login)
From your terminal at your application project root run:
npm ls next react react-dom @supabase/supabase-js @supabase/ssr
Installing
Install Guestbook Package
From your existing Next.js app root, install y2k-guestbook from GitHub:
npm install y2k-guestbook@github:beck-chan/y2k-guestbook @supabase/supabase-js @supabase/ssr
Set Up Environment Variables
-
Copy the
.env.examplefile to.env.local:cp node_modules/y2k-guestbook/.env.example .env.local
-
Fill in values from your Supabase project and site origin:
# Supabase project URL NEXT_PUBLIC_SUPABASE_URL=https://<your-database-url>.supabase.co # Supabase publishable key (browser-safe, RLS still applies) NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=sb_publishable_<your-publishable-key> # Secret key. Local ONLY — for `npx y2k-guestbook allow-admin` SUPABASE_SECRET_KEY=sb_secret_<your-secret-key> # App origin for OAuth return. Used to build redirectTo on the server. SITE_URL=http://localhost:3000 # Supabase pooler URI — for rate limiting DATABASE_URL=postgresql://postgres.<your-database-url>:[YOUR-PASSWORD]@<your-database-region>.pooler.supabase.com:<port>/postgres # Optional admin URL prefix (default /admin). No trailing slash. # NEXT_PUBLIC_GUESTBOOK_ADMIN_PATH=/admin
Enable Authentication Hook
-
Copy the contents of
schema.sqlto your clipboard. -
Within Supabase, select SQL Editor from the left sidebar, then paste in the contents of
schema.sql. -
Click Run to execute the schema.
-
If you receive a Potential issue detected popup, click Run query to execute the schema.
-
Within Supabase, select Authentication from the left sidebar, then click Auth Hooks.
-
Click Add hook, then select Before User Created hook:
- For Hook type select
Postgres. - For Postgres Schema, select
schema.public.
- For Hook type select
-
For Postgres funtion, select
function: hook_before_user_created. -
Click Create hook.
-
Within Supabase, select Authentication from the left sidebar, then click URL Configuration.
-
Confirm that
http://localhost:3000is already entered under Site URL for local previews and builds. -
(Optional, for deployment builds) To enter a redirect URL for deployment:
-
Under Redirect URLs, click Add URL.
-
Paste in your deployment callback URL. This is your
SITE_URLwithauth/callbackappended to the end.For example:
https://<your-project-url>.vercel.app/auth/callback. -
Click Save URLs.
-
Allow Your Admin User
From your Next.js app root, allow-list a Google account as your admin user:
npx y2k-guestbook allow-admin you@gmail.com
You'll need to authorize Google to connect on your first sign in.
Configuring the Application
Protect Admin Login
Next only runs auth/session files from your project. Add three small files. Put proxy.ts next to app/ (repository root, or src/proxy.ts if you use src/app) — not inside app/.
Create proxy.ts to keep the Supabase session fresh and block the admin path (default /admin) unless app_metadata.role === "admin". Next needs config.matcher as a constant in this file:
export { proxy } from "y2k-guestbook/proxy";
export const config = {
matcher: [
"/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp|css)$).*)",
],
};
- The admin login link stays visible, but users without proper access are booted back to the public guestbook comment board and presented with an error.
- Error message copy is hardcoded in
src/components/_shared/AdminAuthErrorOverlay.tsx— not accessible through the admin dashboard settings.
Create the login route at the default path app/admin/login/route.ts (or under your custom admin directory — refer to Add Guestbook Pages: Admin Dashboard below):
export { GET } from "y2k-guestbook/admin-login";
Clicking admin login sends you to Google sign-in. After authenticating, you return to the your configured ${SITE_URL}/auth/callback.
Create app/auth/callback/route.ts, which finishes login and sends you to the right page after Google:
export { GET } from "y2k-guestbook/callback";
Add Guestbook Pages
Next only serves pages from your app/ directory. Re-export the packaged entrypoints:
-
Create
page.tsxfor your public guestbook comment board where you want it to live:export { GuestbookPublicPage as default, guestbookPublicMetadata as metadata, } from "y2k-guestbook"; export const dynamic = "force-dynamic"; -
Set
NEXT_PUBLIC_GUESTBOOK_PATHin.env.localaccording to where your public comment board lives (no trailing slash).Default is the root of your domain (
/):app/page.tsx— When the guestbook is the site, omit the variable (or setNEXT_PUBLIC_GUESTBOOK_PATH=/).app/guestbook/page.tsx— When/(root) is already your site, setNEXT_PUBLIC_GUESTBOOK_PATH=/guestbook.
-
To host your admin dashboard at the default path (
/admin), createapp/admin/page.tsx:export { GuestbookAdminPage as default, guestbookAdminMetadata as metadata, } from "y2k-guestbook"; -
To customize the path for the admin dashboard (for example
/guestbook/admin):-
Set
NEXT_PUBLIC_GUESTBOOK_ADMIN_PATH=/guestbook/adminin.env.local(no trailing slash). -
Create the following re-exports under that directory:
app/guestbook/admin/page.tsx— Your admin dashboard page.app/guestbook/admin/login/route.ts— The admin login route. Refer to Protect Admin Login: Route for more details.app/guestbook/admin/example/route.ts— The theme example route. Refer to Configure Next.js: 2. Set Theme Example Route for more details.
-
Configure Next.js
withGuestbookConfig adds transpilePackages so Next can compile the GitHub-installed package, externalizes pg for rate limiting, and rewrites the view example CSS URL. It reads NEXT_PUBLIC_GUESTBOOK_ADMIN_PATH for that rewrite (default /admin/example.css).
In your next.config.ts (or next.config.js), wrap your existing config with withGuestbookConfig:
import type { NextConfig } from "next";
import { withGuestbookConfig } from "y2k-guestbook/config";
const nextConfig: NextConfig = {
// your existing options
};
export default withGuestbookConfig(nextConfig);
Create app/admin/example/route.ts (or app/guestbook/admin/example/route.ts if you set a custom admin path):
export { GET } from "y2k-guestbook/example-css";
export const dynamic = "force-static";
Next cannot statically parse dynamic if it is re-exported from the package — declare it in this file. This is the route that view example loads, and it only works after the config wrapping.
Place two last pieces in your root layout (app/layout.tsx):
-
Import
y2k-guestbook/styles.cssto apply the default look for the comment board and admin dashboard. -
Wrap
{children}inGuestbookProvidersto display the error dialogue when someone signs in with a Google account that is not on the admin list.
import type { Metadata } from "next";
import "y2k-guestbook/styles.css";
import { GuestbookProviders } from "y2k-guestbook";
export const metadata: Metadata = {
title: "y2k guestbook",
description: "Sign the guestbook.",
};
export default function RootLayout({
children,
}: Readonly<{ children: React.ReactNode }>) {
return (
<html lang="en" className="h-full antialiased">
<body className="min-h-full">
<GuestbookProviders>{children}</GuestbookProviders>
</body>
</html>
);
}
Run Development Server
To preview your application locally, run:
# Serves by default at `http://localhost:3000`
npm run dev
Your interface should initially mimic the demo guestbook, but with no hit counter:
Serve Your Guestbook
To build the application locally to upload manually to your hosting provider:
# Linter check for errors
npm run lint
# Compile
npm run build
# Serve build
npm run start
The easiest way to do this is just to connect your guestbook GitHub repository to a Vercel project:
From your Vercel dashboard:
-
If you already have projects with Vercel, click Add New and select Project.
-
Click Import for your guestbook repository, then set the Project Name.
Your project name will become the URL slug for your application if it's unique and available.
-
Click Environment Variables to enter the following variables:
# Supabase project URL NEXT_PUBLIC_SUPABASE_URL=https://<your-database-url>.supabase.co # Supabase publishable key (browser-safe, RLS still applies) NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=sb_publishable_<your-publishable-key> # App origin for OAuth return. Used to build redirectTo on the server. # For example, Vercel: SITE_URL=http://your-project-url.vercel.app # Supabase pooler URI — for rate limiting # MAKE SURE TO TOGGLE THE LOCK ICON TO THE RIGHT OF `Value` FOR THIS KEY TO MAKE IT INVISIBLE!!! DATABASE_URL=postgresql://postgres.<your-database-url>:[YOUR-PASSWORD]@<your-database-region>.pooler.supabase.com:<port>/postgres
What's Next
Manage admin authentication and add analytics to display a hit counter: