Skip to content

TCG-Price-Lookup/tcgvault

Repository files navigation

TCGVault

License: MIT Astro TypeScript Deploy to Cloudflare Pages Deploy to Vercel Deploy to Netlify

Open source TCG collection tracker. Free, self-hostable, server-rendered.

Track your card collection across 8 TCGs. Know your total value. Export your data. Clone, set API key, deploy in 5 minutes.

TCGVault Screenshot


What is TCGVault?

TCGVault is a self-hostable web app for tracking your trading card game collection. You deploy it with your API key from tcgpricelookup.com set as an environment variable — the key lives on the server, never in the browser. Your collection is stored in your browser's localStorage. No account, no cloud database.


Features

  • 8 TCGs: Pokemon, MTG, Yu-Gi-Oh!, Lorcana, One Piece, Star Wars: Unlimited, Flesh and Blood, Pokemon Japan
  • Live pricing: Real-time prices via TCG Price Lookup API, fetched server-side
  • Secure: API key in .env on the server — never exposed to the browser
  • Export: Download your collection as JSON or CSV
  • Self-hostable: Deploy to Cloudflare Pages, Vercel, Netlify, or run locally
  • Open source: MIT licensed, PRs welcome
  • i18n: Available in English (default) and Japanese (/ja/)

Quick start

1. Get an API key

Get a free API key at tcgpricelookup.com/pricing — 200 requests/day, no credit card required.

2. Deploy

One-click deploy (set TCG_API_KEY in environment variables during setup):

Deploy to Cloudflare Pages Deploy to Vercel Deploy to Netlify

3. Or run locally

git clone https://github.com/TCG-Price-Lookup/tcgvault
cd tcgvault
cp .env.example .env
# Add your TCG_API_KEY to .env
npm install
npm run dev

Open http://localhost:4321 and start tracking your collection.


Environment variables

Variable Description
TCG_API_KEY Your TCG Price Lookup API key (required)

Create .env from the example:

cp .env.example .env

Then edit .env and replace your_api_key_here with your actual key.


How it Works

TCGVault uses Astro hybrid output with the Cloudflare Pages adapter:

  1. Landing pages (/, /about) are pre-rendered as static HTML
  2. API routes (/api/search, /api/card, /api/batch, /api/games) run server-side and call the TCG Price Lookup API using TCG_API_KEY from the environment
  3. The React app (/app) calls these API routes via fetch() — no SDK in the browser
  4. Your collection is stored in localStorage as JSON
Your Browser
  ├── localStorage: collection
  └── fetch() → /api/search (your server)
         └── TCGVault Server → tcgpricelookup.com (TCG_API_KEY from env)

API key in browser: never

Tech Stack

Layer Technology
Framework Astro 5 — hybrid output
Adapter @astrojs/cloudflare
UI React 19 — interactive islands
Styling Tailwind CSS 4 via @tailwindcss/vite
Prices @tcgpricelookup/sdk — server-side only
Language TypeScript (strict mode)
Deploy Cloudflare Pages (primary), Vercel, Netlify

Project Structure

tcgvault/
├── .env.example            # Copy to .env, add TCG_API_KEY
├── astro.config.mjs        # hybrid output + cloudflare adapter
├── src/
│   ├── styles/global.css
│   ├── layouts/BaseLayout.astro
│   ├── pages/
│   │   ├── index.astro         # Landing page (prerendered)
│   │   ├── app.astro           # Collection tracker (prerendered shell)
│   │   ├── about.astro         # How it works (prerendered)
│   │   └── api/                # Server-rendered API routes
│   │       ├── search.ts       # GET /api/search?q=...&game=...
│   │       ├── card.ts         # GET /api/card?id=...
│   │       ├── batch.ts        # POST /api/batch { ids: string[] }
│   │       └── games.ts        # GET /api/games
│   ├── components/
│   │   ├── Header.astro
│   │   ├── Footer.astro
│   │   ├── Hero.astro
│   │   ├── Features.astro
│   │   ├── CTA.astro
│   │   └── app/                # React islands
│   │       ├── App.tsx
│   │       ├── SearchBar.tsx
│   │       ├── CardSearchResults.tsx
│   │       ├── CollectionList.tsx
│   │       ├── CardDetail.tsx
│   │       ├── GameFilter.tsx
│   │       ├── ExportMenu.tsx
│   │       ├── EmptyState.tsx
│   │       └── Settings.tsx
│   └── lib/
│       ├── storage.ts          # localStorage wrapper (collection only)
│       ├── client.ts           # Placeholder (SDK used server-side only)
│       └── types.ts            # Shared TypeScript types
└── public/
    ├── favicon.svg
    └── robots.txt

localStorage Schema

// Keys used
"tcgvault:collection"  CollectionItem[]

// CollectionItem
{
  id: string          // Card UUID from API
  name: string
  game: string        // e.g. "pokemon", "mtg"
  set: string         // Set name
  setCode: string     // Set slug
  number: string      // Card number
  quantity: number
  condition: "near_mint" | "lightly_played" | "moderately_played" | "heavily_played" | "damaged"
  addedAt: string     // ISO timestamp
  cachedPrice?: number
  imageUrl?: string
}

Contributing

PRs and issues are welcome. Please open an issue first for major changes.

  1. Fork the repo
  2. Create a feature branch: git checkout -b feat/my-feature
  3. Commit your changes
  4. Open a pull request

Related Projects


License

MIT — see LICENSE.


Built with TCG Price Lookup API · Docs · GitHub

About

Open source TCG collection tracker — BYOK, self-hostable, zero backend. Supports Pokemon, MTG, Yu-Gi-Oh, Lorcana, One Piece, SWU, Flesh and Blood, Pokemon Japan.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors