- Go 50.5%
- Vue 19.7%
- CSS 17.2%
- TypeScript 10.9%
- HTML 1.7%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
- New theme.ts composable: preference (light, dark, system) persisted in localStorage, applied as data-theme on <html>, live updates when the browser/OS color scheme changes - Defaults to "system" so the theme is detected from browser settings - ThemeToggle component in the navigation (sun/moon/monitor icons) - Dark color palette via CSS variables, color-scheme: dark, smooth transitions - Inline script in index.html applies the theme before first render to avoid a flash of the wrong theme |
||
| backend | ||
| docs | ||
| frontend | ||
| .gitignore | ||
| README.md | ||
TRX Shortlink
Fast, self-hosted URL shortening — one Go process, a slick Vue 3 frontend and SQLite storage.
📖 About
TRX Shortlink turns long, ugly URLs into short, shareable links. It is deliberately small and dependency-friendly:
- One backend process (Go) serves both the JSON API and the built frontend — deploy a single service and you are done.
- SQLite keeps all state in one file. No database server to install, back up, or babysit.
- The Vue 3 + Vite frontend provides a clean, responsive UI for shortening links, logging in and managing existing links.
✨ Features
- 🔗 Shorten any
http(s)URL to a compact 6-character link (https://your-host/a7x2k9) - 🚀 Instant redirects with per-link click counting
- 🔐 Session-based authentication — bcrypt-hashed passwords, HttpOnly session cookies
- 🛠 Admin panel — browse all links, see click stats, copy and delete them
- 📦 Single-binary deployment — the Go server statically serves the compiled frontend
- ⚙️ Sensible configuration — everything tunable via environment variables or a
.envfile - 🌗 Dark mode — follows the browser/OS setting automatically, with a manual light/dark/system toggle that is remembered
- 🪶 Light stack — Go standard library router, pure-Go SQLite driver (no CGO), zero frontend state libraries
🖥️ Tech Stack
| Layer | Technology |
|---|---|
| Frontend | Vue 3 · Vite 7 · vue-router · TypeScript |
| Backend | Go standard library net/http router (Go 1.22+ patterns) |
| Database | SQLite via modernc.org/sqlite (pure Go, no CGO) |
| Auth | golang.org/x/crypto/bcrypt password hashing + HttpOnly session cookies |
📂 Project Structure
trxshortlink/
├── backend/ # Go HTTP server
│ ├── main.go # entry point: config, wiring, graceful shutdown
│ └── internal/
│ ├── config/ # environment & .env configuration
│ ├── database/ # SQLite schema, migrations and queries
│ ├── session/ # in-memory session store + cookie handling
│ ├── api/ # JSON handlers, middleware, router
│ └── web/ # SPA static file server (index.html fallback)
├── frontend/ # Vue 3 + Vite application
│ ├── public/ # static assets (favicon)
│ └── src/
│ ├── api.ts # typed API client
│ ├── auth.ts # shared auth state (composable)
│ ├── router.ts # vue-router setup + auth guard
│ ├── App.vue # layout: header, navigation, footer
│ ├── style.css # global styles (logo color palette)
│ └── pages/ # Home, Login, Admin, CopyLink views
└── docs/ # logo and other documentation assets
🚀 Getting Started
Prerequisites
| Tool | Version | Download |
|---|---|---|
| Go | ≥ 1.26 | https://go.dev/dl/ |
| Node.js/npm | ≥ 20 (only needed to build the frontend) | https://nodejs.org/ |
1. Clone the repository
git clone https://git.dietzlabs.net/Tronax/trxshortlink.git
cd trxshortlink
2. Development mode (two processes, hot reload)
Start the Go backend (terminal 1):
cd backend
go run .
# trxshortlink: TRX Shortlink listening on :8080 (base URL http://localhost:8080)
Start the Vite dev server (terminal 2):
cd frontend
npm install
npm run dev
# ➜ Local: http://localhost:5173/
Open http://localhost:5173. The dev server transparently proxies every
/api/* request to the backend on port 8080, so no CORS setup is needed.
3. Production mode (one process serves everything)
Build the frontend, then let Go serve it:
# build the frontend into frontend/dist
cd frontend
npm install
npm run build
# serve API + frontend from the Go binary
cd ../backend
go build -o trxshortlink-server .
./trxshortlink-server
The app is now available at http://localhost:8080 — short links, the SPA and the JSON API all on one origin.
By default the server looks for the built frontend in
../frontend/dist(relative to the backend working directory). PointDIST_DIRelsewhere if you deploy differently. If the directory is missing, the API still works and a warning is logged.
🔑 Default admin account
On first start an account with the username admin and password
admin is created so you can try the admin panel immediately.
⚠️ Change this before exposing the service! Set
ADMIN_PASSWORDbefore the first start, or delete the row from theuserstable and restart with new credentials. Existing accounts are never overwritten.
⚙️ Configuration
All settings are read from environment variables. A backend/.env file is
also supported (KEY=value per line); real environment variables always win.
| Variable | Default | Description |
|---|---|---|
PORT |
8080 |
HTTP port the server listens on |
DB_PATH |
data/trxshortlink.db |
SQLite database file (created if missing) |
BASE_URL |
http://localhost:PORT |
Public base URL used to build short links |
DIST_DIR |
../frontend/dist |
Folder containing the built frontend |
ADMIN_USERNAME |
admin |
Username of the initial admin account |
ADMIN_PASSWORD |
admin |
Password of the initial admin account |
SESSION_SECURE_COOKIES |
false |
Set to true behind HTTPS so cookies get Secure |
🔌 API Reference
| Method | Path | Auth required | Description |
|---|---|---|---|
GET |
/api |
– | Service info (name, version, status) |
POST |
/api/shorten |
– | Create a short link |
GET |
/{id} |
– | Redirect to the original URL |
POST |
/api/login |
– | Log in, sets the session cookie |
GET |
/api/check-auth |
– | Check whether the session is valid |
POST |
/api/logout |
– | Destroy the current session |
GET |
/api/links |
✅ | List all links with click counts |
DELETE |
/api/links/{id} |
✅ | Delete a link |
Examples
Create a short link:
curl -X POST http://localhost:8080/api/shorten \
-H "Content-Type: application/json" \
-d '{"original_url": "https://example.com/some/very/long/path"}'
{
"id": "a7x2k9",
"short_url": "http://localhost:8080/a7x2k9",
"original_url": "https://example.com/some/very/long/path"
}
Follow it (get redirected):
curl -i http://localhost:8080/a7x2k9
# HTTP/1.1 302 Found
# Location: https://example.com/some/very/long/path
Log in and list links:
curl -c cookies.txt -X POST http://localhost:8080/api/login \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": "admin"}'
curl -b cookies.txt http://localhost:8080/api/links
All errors are reported as JSON in the form {"error": "message"}.
🗺️ Roadmap
- Custom slugs (
/my-meetinginstead of/a7x2k9) - QR codes for every short link
- Optional user registration & multi-user admin views
- Docker / docker-compose deployment
- Click statistics charts in the admin panel
🤝 Contributing
Pull requests are welcome! For larger changes, please open an issue first so we can discuss what you would like to change.
- Fork the repository and create your branch from
main - Make your changes (
gofmt,go vet ./...andnpm run buildshould pass) - Open a pull request
📄 License
This project is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License (CC BY-NC-SA 4.0).
👤 Author
Tronax — git.dietzlabs.net/Tronax