🐾 Nah.pet – Open Source URL Shortener

Nah.pet – "Rewriting paths with bad energy" ✨
Open-source URL shortener with custom domains and analytics.

πŸ“š OpenAPI Documentation


✨ Features

  • βœ‚οΈ URL Shortening with custom slugs
  • πŸ” Password protection for sensitive links
  • ⏰ Automatic link expiration
  • πŸ“Š Detailed analytics (clicks, geolocation, browsers)
  • 🌐 Custom domains with complete isolation
  • πŸ‘₯ Admin system with manual approval
  • πŸ”‘ REST API with API key authentication
  • 🌍 Multilingual interface

🌍 Translation Status

Managed with Paraglide JS and Weblate for type-safety.


🌐 Custom Domains

Why cat.yourDomain.tld?

The cat. prefix bypasses CORS restrictions from Cloudflare and other CDNs by using a dedicated subdomain.

DNS Setup

  1. Domain verification:

    • DNS: TXT record with token
    • File: /.well-known/nah-pet-verification.txt
  2. CNAME configuration:

    Type: CNAME
    Name: cat.example.com
    Value: cat.nah.pet
    TTL: 300
    
  3. Redirection:

    https://cat.example.com/abc123 β†’ CNAME β†’ cat.nah.pet β†’ nah.pet
    

Each custom domain is fully isolatedβ€”no access to system routes (/admin, /login, etc.).


πŸš€ Installation

🐳 Docker Compose

git clone https://github.com/anhostfr/nah.pet
cd link-shortener

cp .env.example .env
# Edit variables
# DATABASE_URL=postgresql://user:password@postgres:5432/nahpet
# PUBLIC_MAIN_DOMAIN=your-domain.com
# [email protected]
# OAUTH_CLIENT_ID=your_oauth_id (optional)
# OAUTH_CLIENT_SECRET=your_oauth_secret (optional)

docker-compose up -d

Access:

  • Web interface: http://localhost:3000
  • API: http://localhost:3000/doc

πŸ› οΈ Manual Installation

bun install
createdb nahpet
cp .env.example .env  # Edit variables
bunx prisma migrate deploy
bun run dev

πŸ”Œ REST API

Built with sveltekit-api from JacobLinCool, OpenAPI 3.0 specification.

Main Endpoints

  • GET /api/v1/links – List links
  • POST /api/v1/links – Create a link
  • GET/PUT/DELETE /api/v1/links/{id} – Manage a link
  • GET /api/v1/stats – Global statistics
  • GET /api/v1/stats/{slug} – Link statistics
  • POST /api/v1/links/bulk – Bulk operations
  • GET /api/v1/stats/export – Export data

SDK Generation

npm install @openapitools/openapi-generator-cli -g

curl -o openapi.json https://your-domain.com/api/v1/openapi.json

openapi-generator-cli generate \
  -i openapi.json \
  -g typescript-axios \
  -o ./sdk-typescript

Authentication

curl -H "Authorization: Bearer YOUR_API_KEY" \
     "https://your-domain.com/api/v1/links"

πŸ—οΈ Tech Stack

  • Frontend/Backend: SvelteKit 5 + TypeScript
  • Runtime: Bun 1.x
  • Database: PostgreSQL + Prisma ORM
  • Authentication: Lucia Auth + OAuth2
  • Styling: TailwindCSS 4 + Shadcn/ui
  • i18n: Paraglide JS
  • API: Sveltekit-api (OpenAPI)
  • Deployment: Docker + Docker Compose

Project Structure

src/
β”œβ”€β”€ routes/          # Pages and API
β”œβ”€β”€ lib/
β”‚   β”œβ”€β”€ components/  # Svelte components
β”‚   β”œβ”€β”€ server/      # Server logic
β”‚   └── paraglide/   # Translations
└── api/v1/           # API definitions

πŸ› οΈ Development

bun run dev        # Development
bun run build      # Production
bun run check      # TypeScript check
bun run format     # Prettier formatting

bunx prisma studio
bunx prisma generate
bunx prisma migrate dev

Environment Variables

DATABASE_URL=postgresql://postgres:password@localhost:5432/nahpet
PUBLIC_MAIN_DOMAIN=localhost:5173
[email protected]
OAUTH_CLIENT_ID=your_oauth_client_id (optional)
OAUTH_CLIENT_SECRET=your_oauth_client_secret (optional)

Screenshots

Dashboard Screenshot
Dashboard
Analytics Screenshot
Analytics
Analytics Slug Screenshot
Analytics (Slug)

🀝 Contributing

Translations

cp messages/en.json messages/es.json  # Add Spanish
# Add "es" in project.inlang/settings.json

Code

  1. Fork the repository
  2. Create a branch feature/my-feature
  3. Develop with bun run dev
  4. Check with bun run check + bun run format
  5. Open a Pull Request

πŸ“„ License

MIT – see LICENSE


πŸ™ Acknowledgements


"It's a no from us, dawg." – but it's a yes for open source!

Top categories

Loading Svelte Themes