Home
Softono

Nah.pet

Open source MIT Svelte
154
Stars
3
Forks
2
Issues
0
Watchers
8 months
Last Commit

 About Nah.pet

Rewriting paths with bad energy - An alternative to TinyURL, YOURLS, Shlink

Platforms

Web Self-hosted

Languages

Svelte

Links

Need Help Installing Nah.pet?

We provide expert installation service for this software. Our team will install, configure, and secure Nah.pet on your server. plans start at just $30.

🐾 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
# [email protected]
# OAUTH_CLIENT_ID=your_oauth_id (optional)
# OAUTH_CLIENT_SECRET=your_oauth_secret (optional)
# PUBLIC_DOC=false (set to 'true' for public API docs)
# PUBLIC_ALLOW_REGISTRATION=true (set to 'false' to disable registration)

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)

# Access control (optional)
PUBLIC_DOC=false                      # Set to 'true' to make API docs public
PUBLIC_ALLOW_REGISTRATION=true        # Set to 'false' to disable registration

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!