Trace every book on the web — free, verified, and open.
This repo contains the open-source MVP of Book Trace: a Next.js app that indexes book metadata (not files) and connects readers to publicly available sources such as OpenLibrary, Archive.org, publishers, GitHub, and verified repositories.
- No Login Required: everything open and accessible
- No Piracy: index only publicly available or official links
- Knowledge for All: free, student-friendly
- Transparency First: clear labeling of Free, Verified, Paid, Open Source
- Zero Cost Stack: free-tier friendly infra
- Next.js 14+ (App Router) + TypeScript
- TailwindCSS; light, content-first theme
- shadcn/ui (optional styles/components)
- Supabase (free tier) for database + querying
- Deploy on Vercel
Directory overview
app/— routes and pages (App Router)page.tsx— home (hero + search + CTA)search/page.tsx— search results + sections (Related/Popular/Trending placeholders)library/page.tsx— browsable library (filters + pagination)book/[id]/page.tsx— book detailsapi/seed/route.ts— inserts example dataseed/page.tsx— UI to trigger seed
components/— shared UISearchBar.tsx— debounced search with suggestionsFilterSidebar.tsx— labels/topics/types/author filters + topics autocompletePagination.tsx— reusable paginationBookCard.tsx— cover/title/author + primary badgeSourceBadge.tsx— badges with emojis (🆓/✅/💰/💾)ContributeForm.tsx— embedded Tally form for user submissions
lib/— types and Supabase client + data utilitiessupabase/client.ts— browser clientsupabase/books.ts— search + filters + pagination + book by idsupabase/topics.ts�� topics suggestionssupabase/suggestions.ts— title/author/topic suggestionstypes.ts— DB rows and UI models (+ mappers)
Assets
public/ods-logo.svg— Open Dev Society mock logopublic/books-animation.json— Lottie animation for home hero
Create .env.local with your Supabase project:
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
# Optional: Tally embed (if using a different form than the default)
NEXT_PUBLIC_TALLY_CONTRIBUTE_URL=https://tally.so/embed/wa7vGZ?alignLeft=1&hideTitle=1&transparentBackground=1&dynamicHeight=1Install and run locally:
npm install
npm run dev
# open http://localhost:3000-- Books
create table books (
id uuid primary key default gen_random_uuid(),
title text not null,
isbn text,
author text,
cover_url text,
description text,
published_year integer,
created_at timestamp default now()
);
-- Book labels
create table book_labels (
id uuid primary key default gen_random_uuid(),
book_id uuid references books(id) on delete cascade,
label text not null,
unique(book_id, label)
);
-- Book topics
create table book_topics (
id uuid primary key default gen_random_uuid(),
book_id uuid references books(id) on delete cascade,
topic text not null,
unique(book_id, topic)
);
-- Sources
create table sources (
id uuid primary key default gen_random_uuid(),
book_id uuid references books(id) on delete cascade,
source_name text,
url text not null,
type text,
verified boolean default false,
format text,
added_at timestamp default now()
);Row Level Security (RLS) for public read (anon key):
alter table public.books enable row level security;
create policy "Public read books" on public.books for select using (true);
alter table public.book_labels enable row level security;
create policy "Public read labels" on public.book_labels for select using (true);
alter table public.book_topics enable row level security;
create policy "Public read topics" on public.book_topics for select using (true);
alter table public.sources enable row level security;
create policy "Public read sources" on public.sources for select using (true);lib/types.tsmodels raw rows (BookRow,BookLabelRow,BookTopicRow,SourceRow) and joined shapes (BookJoined).mapBookJoinedToBookconverts to a UI-friendlyBookmodel.lib/supabase/books.tsfetchBooks({ query, filters, page, pageSize })- Search across
title,author,isbn - Filters:
.in("book_labels.label"),.in("book_topics.topic"),.in("sources.type") - Exact count + range pagination (50/page default)
- Search across
fetchBookById(id)returns a single book with relatedlabels,topics,sources.
lib/supabase/topics.ts— distinct topic suggestions viailike+ client dedupelib/supabase/suggestions.ts— suggestions across titles, authors, topics
Pages
/Home: split hero with animated Lottie, headline (“Find every book. Everywhere.”), large search, quick tags (Browse, Authors, Free, Verified), CTAs to Explore Library and Contribute./libraryLibrary: left filters, floating search bar, top/bottom pagination, 50/books per page./searchSearch: search-focused results + placeholder sections for Related/Popular/Trending./book/[id]Book Details: cover, title, author, ISBN, description, labels, topics, sources (with badges), disclaimers, “More works by Author”, and a placeholder “People also traced…” grid./seedSeed: button to insert example data.
Components
- SearchBar: debounced input, suggestions dropdown, optional submit button; supports large hero variant.
- FilterSidebar: author text filter; quick chips for labels/types; topics autocomplete with suggestions; multi-select chips.
- Pagination: compact, Amazon-style page navigation.
- BookCard: cover, title, author, primary source badge; subtle hover tilt/shadow.
- SourceBadge: clearly labeled badges (🆓 Free, ✅ Verified, 💰 Paid, 💾 Open Source).
- ContributeForm: togglable section that embeds Tally.
Branding & Theme
- Clean, minimal, content-focused; black text on light background.
- Sticky header with logo + social links; sleek translucent footer centered © line and a one-line links row.
- Disclaimers near sources and in footer about connecting to knowledge, not files.
Visit http://localhost:3000/seed and click "Run Seed" to insert example rows into books, book_labels, book_topics, and sources via POST /api/seed.
We welcome contributions of metadata and sources. Use the inline Tally form from the no-results area or the library quick links.
- Embedded Tally form (default):
https://tally.so/embed/wa7vGZ?alignLeft=1&hideTitle=1&transparentBackground=1&dynamicHeight=1(Tally Embed) - Optional env override:
NEXT_PUBLIC_TALLY_CONTRIBUTE_URL
Implemented
- Supabase integration (client + queries)
- Normalized schema with labels/topics/sources
- Library listing with filters, debounce search, and pagination (50/page)
- Search page with suggestions and extra placeholder sections
- Book details page with badges, disclaimers, and related placeholders
- Home hero with Lottie animation and branding
- Seed route + page for example data
- Contribute form embedded via Tally; quick links + buttons
Next Ideas
- URL-synced filters (labels/types/topics/author) across pages
- Actual related/popular/trending recommendations
- Admin moderation queue for submissions
- Analytics on search and click-through (privacy-respecting)
- Book Trace does not host or distribute files.
- Links point to external hosts; availability and legality are determined by the hosts.
- Support authors and publishers by buying official copies when possible.
npm run dev # start local dev server
npm run build # build for production
npm run start # start production build locallyDeploy to Vercel. Provide the environment variables:
NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEY- (optional)
NEXT_PUBLIC_TALLY_CONTRIBUTE_URL
Ensure RLS select policies are enabled for public read as shown above.