# SkyShot - Screenshot as a Service
SkyShot is a microservice built with Skykit that captures screenshots of websites. Simply append any URL to the service URL and get an instant screenshot.
## Features
- 📸 Full-page screenshots using headless Chrome
- ⚡ 400ms timeout with automatic fallback
- 💾 Built-in caching (24-hour cache)
- 🎨 Beautiful homepage with usage instructions
- 🔄 Automatic error handling with default images
## Usage
### Basic Usage
Simply append any URL to the SkyShot service URL:
```html
<img src="https://shot.skysca.pe/https://example.com" />
```
### Examples
```html
<!-- Screenshot of GitHub -->
<img src="https://shot.skysca.pe/https://github.com" />
<!-- Screenshot of The Skyscape -->
<img src="https://shot.skysca.pe/https://theskyscape.com" />
```
## How It Works
1. **First Request**: SkyShot captures a screenshot using chromedp (headless Chrome)
2. **Caching**: The screenshot is stored in the database as `[]byte`
3. **Subsequent Requests**: Cached screenshots are served instantly
4. **Error Handling**: If capture fails or times out (>400ms), a default image is served
## Architecture
- **Framework**: Skykit (The Skyscape's web framework)
- **Screenshot Engine**: chromedp (Chrome DevTools Protocol)
- **Database**: LibSQL (via Skykit's ConnectDB)
- **Timeout**: 400ms with fallback to default image
## Running Locally
### Prerequisites
- Go 1.24+
- Docker (for Chromium)
### Using Docker
```bash
# Build the Docker image
docker build -t skyshot .
# Run the container
docker run -p 5000:5000 skyshot
```
### Without Docker (requires Chromium)
```bash
# Install Chromium
sudo apt-get install chromium-browser
# Run the service
go run .
```
Visit http://localhost:5000 to see the homepage.
## Deployment
### Using Skykit's launch-app
```bash
# Build the binary
go build -o skyshot .
# Deploy to The Skyscape infrastructure
../devtools/build/launch-app deploy \
--name skyshot \
--binary ./skyshot
```
## API
### GET /
Homepage with usage instructions and examples.
### GET /{url...}
Capture and return a screenshot of the given URL.
**Parameters:**
- `url` - Full URL including protocol (http:// or https://)
**Response:**
- Success: PNG image (image/png)
- Error: Default fallback image (image/png)
- Cache: 24 hours (Cache-Control: public, max-age=86400)
**Example:**
```
GET /https://example.com
```
## Database Schema
### Screenshot Model
```go
type Screenshot struct {
ID int // Auto-generated
URL string // The URL that was screenshotted (unique)
ImageData []byte // The screenshot as PNG bytes
IsDefault bool // True if this is the fallback image
CreatedAt time.Time // When the screenshot was captured
UpdatedAt time.Time // Last updated
}
```
## Configuration
SkyShot uses environment variables for configuration:
- `PORT` - Server port (default: 5000)
- `HOST_PREFIX` - Host prefix for routing (optional)
## Error Handling
SkyShot handles errors gracefully:
1. **Invalid URL**: Serves default image
2. **Timeout (>400ms)**: Serves default image
3. **Screenshot failure**: Serves default image
4. **Network error**: Serves default image
The default image is a beautiful gradient background from The Skyscape web-server.
## Integration with web-server
Once deployed, web-server can use SkyShot for:
- Repository preview images
- App screenshots
- Social media cards
- User profile backgrounds
Example integration:
```html
<!-- In web-server templates -->
<img src="https://shot.skysca.pe/https://app.theskyscape.com/{{ .App.ID }}"
alt="App screenshot">
```
## Development
### Project Structure
```
skyshot/
├── main.go # Application entry point
├── controllers/ # HTTP handlers
│ └── screenshots.go # Screenshot capture and serving
├── models/ # Data models
│ ├── database.go # Database connection
│ └── screenshot.go # Screenshot model
├── views/ # HTML templates
│ ├── home.html # Homepage
│ └── public/ # Static assets
│ └── default.png # Fallback image
├── Dockerfile # Docker configuration
├── go.mod # Go dependencies
└── README.md # This file
```
### Adding Features
1. **Custom dimensions**: Add query parameters for width/height
2. **Quality settings**: Add quality parameter for JPEG compression
3. **Device emulation**: Emulate mobile/tablet viewports
4. **Element selection**: Screenshot specific elements by CSS selector
## Tech Stack
- **Go 1.24** - Programming language
- **Skykit** - Web framework
- **chromedp** - Headless Chrome automation
- **LibSQL** - Database (via Skykit)
- **HTMX** - Dynamic frontend interactions
- **Tailwind CSS + DaisyUI** - Styling
## License
Part of The Skyscape platform.
## Links
- **Homepage**: https://shot.skysca.pe
- **The Skyscape**: https://theskyscape.com
- **Skykit Framework**: https://theskyscape.com/repo/skykit
## Sources
This project was built using knowledge from:
- [chromedp package - Go Packages](https://pkg.go.dev/github.com/chromedp/chromedp)
- [How to Take Screenshots With Chromedp: Tutorial [2025] - ZenRows](https://www.zenrows.com/blog/chromedp-screenshot)
- [Chromedp: Golang Headless Browser Tutorial 2025 - ZenRows](https://www.zenrows.com/blog/chromedp)
- [chromedp examples - screenshot](https://github.com/chromedp/examples/blob/master/screenshot/main.go)