A modern Node.js API that fetches Spotify song data and provides a beautiful documentation interface. Built with Express, TypeScript, and Vite.
- Real-time Spotify Integration - Get currently playing or recently played songs
- Beautiful SVG Generation - Glassmorphism design with shiny text effects and visualizer
- Interactive Documentation - Beautiful web interface with live API testing
- Modern Tech Stack - TypeScript, Express, Vite, ES Modules
- Security First - CORS, Helmet, and environment variable protection
- Fast Development - Hot reload with Vite and Nodemon
- Node.js 18+
- npm or yarn
- Spotify Developer Account
-
Clone the repository
git clone <your-repo-url> cd tanu-api
-
Install dependencies
npm install
-
Set up environment variables
cp .env.example .env
Edit
.envwith your Spotify credentials:SPOTIFY_CLIENT_ID=your_client_id SPOTIFY_CLIENT_SECRET=your_client_secret SPOTIFY_REFRESH_TOKEN=your_refresh_token PORT=8080
-
Build and start
npm run build npm start
Or for development:
npm run dev
-
Visit the documentation Open http://localhost:8080 in your browser
Live Demo: https://tanuapi.vercel.app
Returns the currently playing song or the most recently played song.
Response:
{
"isPlaying": true,
"title": "Song Title",
"artist": "Artist Name",
"album": "Album Name",
"albumImageUrl": "https://...",
"songUrl": "https://open.spotify.com/track/...",
"previewUrl": "https://...",
"duration": 180000,
"progress": 45000
}Returns an SVG image showing the current/recent song data. Perfect for README files!
Features:
- Glassmorphism design with shiny text effects
- Shows playing status with visual indicators
- Progress bar for currently playing songs
- Always-visible visualizer bars
- Responsive 460x120px size
- Automatic text truncation for long titles
Usage in README:
Live Example:
Alternative formats:
- Simple SVG: View Simple SVG (no external images)
- Full SVG: View Full SVG (with album art)
- Mobile version: Mobile SVG
- Test SVG:
🔧 Troubleshooting SVG Display
If the SVG doesn't display above, try:
- Direct URL: https://tanuapi.vercel.app/api/svg
- Check if API is running: https://tanuapi.vercel.app/health
- View JSON data: https://tanuapi.vercel.app/api/song
The SVG might not display if:
- Spotify API credentials are not configured
- No recent Spotify activity
- GitHub is caching the image
Health check endpoint for monitoring.
npm run dev- Start development server with hot reloadnpm run build- Build for productionnpm start- Start production servernpm run preview- Preview production build
tanu-api/
├── src/
│ ├── api/
│ │ └── song.ts # Song API routes
│ ├── services/
│ │ └── spotify.service.ts # Spotify integration
│ └── index.ts # Main server file
├── public/
│ └── index.html # Documentation page
├── dist/ # Built files
└── package.json
| Variable | Description | Required |
|---|---|---|
SPOTIFY_CLIENT_ID |
Your Spotify app client ID | Yes |
SPOTIFY_CLIENT_SECRET |
Your Spotify app client secret | Yes |
SPOTIFY_REFRESH_TOKEN |
Your Spotify refresh token | Yes |
PORT |
Server port (default: 8080) | No |
NODE_ENV |
Environment (development/production) | No |
- Go to Spotify Developer Dashboard
- Create a new app
- Get your Client ID and Client Secret
- Set up OAuth to get a refresh token
- Glassmorphism Design - Beautiful glass effect with blurred album background
- Shiny Text Effects - Animated gradient text with shimmer effects
- Always-Visible Visualizer - Animated bars when playing, static when paused
- Real-time Updates - Live song data with album artwork
- Responsive Design - Works on desktop and mobile (
?mobile=true) - Progress Bar - Shows current playback progress with animated pin
- Error Handling - Graceful fallbacks for API failures
- Caching - Smart token caching for optimal performance
API Documentation: https://tanuapi.vercel.app
Direct SVG: https://tanuapi.vercel.app/api/svg
Mobile Version: https://tanuapi.vercel.app/api/svg?mobile=true
MIT License - see LICENSE file for details
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
Found a bug? Please open an issue on GitHub with:
- Description of the problem
- Steps to reproduce
- Expected vs actual behavior
- Environment details