Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

anhostfr/nah.pet

Repository files navigation

🐾 Nah.pet – Open Source URL Shortener

License: MIT SvelteKit TypeScript

Translation status Translation status

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

Translation status Translation status

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
# ADMIN_EMAIL=admin@example.com
# 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
ADMIN_EMAIL=admin@example.com
OAUTH_CLIENT_ID=your_oauth_client_id (optional)
OAUTH_CLIENT_SECRET=your_oauth_client_secret (optional)

Screenshots

🀝 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!

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /