feat: Add VitePress docs, EPUB to PDF tool, Phosphor icons, and licensing updates

- Set up VitePress documentation site (docs:dev, docs:build, docs:preview)
- Added Getting Started, Tools Reference, Contributing, and Commercial License pages
- Created self-hosting guides for Docker, Vercel, Netlify, Cloudflare, AWS, Hostinger, Nginx, Apache
- Updated README with documentation link, sponsors section, and docs contribution guide

- Added EPUB to PDF converter using LibreOffice WASM

- Migrated to Phosphor Icons for consistent iconography

- Added donation ribbon banner on landing page
- Removed 'Like My Work?' section (replaced by ribbon)
- Updated licensing.html with delivery model, AGPL notice, invoicing, and no-refund policy

- Added Commercial License documentation page
- Updated translations table (Chinese added, marked non-English as In Progress)

- Added sponsors.yml workflow for auto-generating sponsor avatars
This commit is contained in:
abdullahalam123
2025-12-27 19:30:31 +05:30
parent 0e888743d3
commit f30a084fce
189 changed files with 59872 additions and 3300 deletions

158
docs/self-hosting/apache.md Normal file
View File

@@ -0,0 +1,158 @@
# Deploy with Apache
Host BentoPDF using Apache HTTP Server.
## Prerequisites
- Apache 2.4+
- mod_rewrite enabled
- SSL certificate (recommended)
## Step 1: Build the Project
```bash
git clone https://github.com/bentopdf/bentopdf.git
cd bentopdf
npm install
npm run build
```
## Step 2: Copy Files
```bash
sudo mkdir -p /var/www/bentopdf
sudo cp -r dist/* /var/www/bentopdf/
sudo chown -R www-data:www-data /var/www/bentopdf
```
## Step 3: Apache Configuration
Create `/etc/apache2/sites-available/bentopdf.conf`:
```apache
<VirtualHost *:80>
ServerName your-domain.com
Redirect permanent / https://your-domain.com/
</VirtualHost>
<VirtualHost *:443>
ServerName your-domain.com
DocumentRoot /var/www/bentopdf
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/your-domain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/your-domain.com/privkey.pem
<Directory /var/www/bentopdf>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
# WASM MIME type
AddType application/wasm .wasm
# Compression
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/css application/javascript application/json application/wasm
</IfModule>
# Cache headers
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/wasm "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
</IfModule>
# Security headers
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
</VirtualHost>
```
## Step 4: .htaccess for SPA Routing
Create `/var/www/bentopdf/.htaccess`:
```apache
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# Don't rewrite files or directories
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite everything else to index.html
RewriteRule ^ index.html [L]
</IfModule>
```
## Step 5: Enable Required Modules
```bash
sudo a2enmod rewrite
sudo a2enmod ssl
sudo a2enmod headers
sudo a2enmod expires
sudo a2enmod deflate
```
## Step 6: Enable the Site
```bash
sudo a2ensite bentopdf.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
```
## Subdirectory Deployment
To host at `/pdf/`:
1. Build with base URL:
```bash
BASE_URL=/pdf/ npm run build
```
2. Update `.htaccess`:
```apache
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /pdf/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.html [L]
</IfModule>
```
## Troubleshooting
### WASM 404 Errors
Ensure MIME type is configured:
```apache
AddType application/wasm .wasm
```
### Rewrite Not Working
Check that mod_rewrite is enabled:
```bash
sudo a2enmod rewrite
```
### Permission Denied
```bash
sudo chown -R www-data:www-data /var/www/bentopdf
sudo chmod -R 755 /var/www/bentopdf
```

132
docs/self-hosting/aws.md Normal file
View File

@@ -0,0 +1,132 @@
# Deploy to AWS S3 + CloudFront
Host BentoPDF on AWS for maximum control and scalability.
## Architecture
```
User → CloudFront (CDN) → S3 (Static Files)
```
## Step 1: Create S3 Bucket
```bash
# Create bucket
aws s3 mb s3://your-bentopdf-bucket --region us-east-1
# Enable static website hosting
aws s3 website s3://your-bentopdf-bucket \
--index-document index.html \
--error-document index.html
```
## Step 2: Build and Upload
```bash
# Build the project
npm run build
# Sync to S3
aws s3 sync dist/ s3://your-bentopdf-bucket \
--delete \
--cache-control "max-age=31536000"
# Set correct MIME types for WASM
aws s3 cp s3://your-bentopdf-bucket/ s3://your-bentopdf-bucket/ \
--recursive \
--exclude "*" \
--include "*.wasm" \
--content-type "application/wasm" \
--metadata-directive REPLACE
```
## Step 3: Create CloudFront Distribution
```bash
aws cloudfront create-distribution \
--origin-domain-name your-bentopdf-bucket.s3.amazonaws.com \
--default-root-object index.html
```
Or use the AWS Console:
1. Go to CloudFront → Create distribution
2. Origin domain: Select your S3 bucket
3. Enable "Origin Access Control"
4. Default root object: `index.html`
5. Create distribution
## Step 4: S3 Bucket Policy
Allow CloudFront to access the bucket:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCloudFrontAccess",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::your-bentopdf-bucket/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::ACCOUNT_ID:distribution/DISTRIBUTION_ID"
}
}
}
]
}
```
## Step 5: Custom Error Pages
Configure 404 to return `index.html` for SPA routing:
1. CloudFront → Error pages
2. Create custom error response:
- HTTP error code: 404
- Response page path: `/index.html`
- HTTP response code: 200
## Cost Estimation
| Resource | Estimated Cost |
|----------|----------------|
| S3 Storage (~500MB) | ~$0.01/month |
| CloudFront (1TB transfer) | ~$85/month |
| CloudFront (10GB transfer) | ~$0.85/month |
::: tip
Use S3 Intelligent Tiering for cost optimization on infrequently accessed files.
:::
## Automation with Terraform
```hcl
# main.tf
resource "aws_s3_bucket" "bentopdf" {
bucket = "your-bentopdf-bucket"
}
resource "aws_cloudfront_distribution" "bentopdf" {
origin {
domain_name = aws_s3_bucket.bentopdf.bucket_regional_domain_name
origin_id = "S3Origin"
}
enabled = true
default_root_object = "index.html"
default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "S3Origin"
viewer_protocol_policy = "redirect-to-https"
}
}
```

View File

@@ -0,0 +1,78 @@
# Deploy to Cloudflare Pages
[Cloudflare Pages](https://pages.cloudflare.com) offers fast, global static site hosting with unlimited bandwidth.
## Quick Deploy
1. Go to [Cloudflare Pages](https://dash.cloudflare.com/?to=/:account/pages)
2. Click "Create a project"
3. Connect your GitHub repository
## Build Configuration
| Setting | Value |
|---------|-------|
| Framework preset | None |
| Build command | `npm run build` |
| Build output directory | `dist` |
| Root directory | `/` |
## Environment Variables
Add these in Settings → Environment variables:
| Variable | Value |
|----------|-------|
| `NODE_VERSION` | `18` |
| `SIMPLE_MODE` | `false` (optional) |
## Configuration File
Create `_headers` in your `public` folder:
```
# Cache WASM files aggressively
/*.wasm
Cache-Control: public, max-age=31536000, immutable
Content-Type: application/wasm
# Service worker
/sw.js
Cache-Control: no-cache
```
Create `_redirects` for SPA routing:
```
/* /index.html 200
```
## Custom Domain
1. Go to your Pages project
2. Click "Custom domains"
3. Add your domain
4. Cloudflare will auto-configure DNS if the domain is on Cloudflare
## Advantages
- **Free unlimited bandwidth**
- **Global CDN** with 300+ edge locations
- **Automatic HTTPS**
- **Preview deployments** for pull requests
- **Fast builds**
## Troubleshooting
### Large File Uploads
Cloudflare Pages supports files up to 25 MB. WASM modules should be fine, but if you hit limits, consider:
```bash
# Split large files during build
npm run build
```
### Worker Size Limits
If using Cloudflare Workers for advanced routing, note the 1 MB limit for free plans.

170
docs/self-hosting/docker.md Normal file
View File

@@ -0,0 +1,170 @@
# Deploy with Docker
The easiest way to self-host BentoPDF in a production environment.
## Quick Start
```bash
docker run -d \
--name bentopdf \
-p 3000:80 \
--restart unless-stopped \
ghcr.io/bentopdf/bentopdf:latest
```
## Docker Compose
Create `docker-compose.yml`:
```yaml
version: '3.8'
services:
bentopdf:
image: ghcr.io/bentopdf/bentopdf:latest
container_name: bentopdf
ports:
- "3000:80"
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80"]
interval: 30s
timeout: 10s
retries: 3
```
Run:
```bash
docker compose up -d
```
## Build Your Own Image
```dockerfile
# Dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
```
Build and run:
```bash
docker build -t bentopdf:custom .
docker run -d -p 3000:80 bentopdf:custom
```
## Environment Variables
| Variable | Description | Default |
|----------|-------------|---------|
| `SIMPLE_MODE` | Build without LibreOffice tools | `false` |
| `BASE_URL` | Deploy to subdirectory | `/` |
Example:
```bash
docker run -d \
-e SIMPLE_MODE=true \
-p 3000:80 \
ghcr.io/bentopdf/bentopdf:latest
```
## With Traefik (Reverse Proxy)
```yaml
version: '3.8'
services:
traefik:
image: traefik:v2.10
command:
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.email=you@example.com"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencrypt
bentopdf:
image: ghcr.io/bentopdf/bentopdf:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.bentopdf.rule=Host(`pdf.example.com`)"
- "traefik.http.routers.bentopdf.entrypoints=websecure"
- "traefik.http.routers.bentopdf.tls.certresolver=letsencrypt"
restart: unless-stopped
```
## With Caddy (Reverse Proxy)
```yaml
version: '3.8'
services:
caddy:
image: caddy:2
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
bentopdf:
image: ghcr.io/bentopdf/bentopdf:latest
restart: unless-stopped
volumes:
caddy_data:
```
Caddyfile:
```
pdf.example.com {
reverse_proxy bentopdf:80
}
```
## Resource Limits
```yaml
services:
bentopdf:
image: ghcr.io/bentopdf/bentopdf:latest
deploy:
resources:
limits:
cpus: '1'
memory: 512M
reservations:
cpus: '0.25'
memory: 128M
```
## Updating
```bash
# Pull latest image
docker compose pull
# Recreate container
docker compose up -d
```

View File

@@ -0,0 +1,223 @@
# Deploy to Hostinger
[Hostinger](https://hostinger.com) is a popular shared hosting provider. This guide covers deploying BentoPDF to Hostinger's shared hosting.
## Prerequisites
- Hostinger hosting plan with file manager access
- Node.js installed locally for building
## Step 1: Build the Project
```bash
git clone https://github.com/alam00000/bentopdf.git
cd bentopdf
npm install
npm run build
```
The built files will be in the `dist` folder.
## Step 2: Upload to Hostinger
### Root Domain Deployment
1. Log in to your Hostinger account
2. Go to **File Manager****public_html**
3. **Delete** any existing files (backup if needed)
4. **Upload** all contents of your local `dist` folder to `public_html`
### Subdirectory Deployment
If deploying to a subdirectory (e.g., `yourdomain.com/pdf-tools/`):
1. Build with the correct base URL:
```bash
BASE_URL=/pdf-tools/ npm run build
```
2. Create the folder in Hostinger:
- Go to **File Manager****public_html**
- Create a new folder: `pdf-tools`
3. Upload all contents of `dist` to `public_html/pdf-tools/`
## Step 3: Create .htaccess File
Create a `.htaccess` file in the root of your deployment folder (`public_html` or `public_html/pdf-tools/`):
::: warning Important
For subdirectory deployment, change `RewriteBase /` to `RewriteBase /pdf-tools/` (or your folder name).
:::
```apache
RewriteEngine On
RewriteBase /
# ============================================
# 1. SECURITY HEADERS (CRITICAL FOR WASM)
# ============================================
<IfModule mod_headers.c>
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set X-XSS-Protection "1; mode=block"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
# REQUIRED for soffice.js (SharedArrayBuffer)
Header always set Cross-Origin-Opener-Policy "same-origin"
Header always set Cross-Origin-Embedder-Policy "require-corp"
</IfModule>
# ============================================
# 2. BROWSER CACHING
# ============================================
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
ExpiresByType image/x-icon "access plus 1 year"
ExpiresByType font/woff2 "access plus 1 year"
ExpiresByType font/woff "access plus 1 year"
ExpiresByType font/ttf "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType application/wasm "access plus 1 year"
ExpiresByType application/gzip "access plus 1 year"
ExpiresByType text/html "access plus 0 seconds"
</IfModule>
# ============================================
# 3. COMPRESSION (STANDARD)
# ============================================
# Prevent server from double-compressing files
SetEnvIfNoCase Request_URI "\.gz$" no-gzip
SetEnvIfNoCase Request_URI "\.br$" no-gzip
SetEnvIfNoCase Request_URI "\.wasm$" no-gzip
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/json
AddOutputFilterByType DEFLATE image/svg+xml
AddOutputFilterByType DEFLATE font/woff
AddOutputFilterByType DEFLATE font/ttf
</IfModule>
# ============================================
# 4. MIME TYPES & SPECIAL FILE HANDLING
# ============================================
AddType application/javascript .js .mjs
AddType application/wasm .wasm
AddType font/woff2 .woff2
AddType font/woff .woff
AddType image/webp .webp
# Handle soffice.wasm.gz correctly
<FilesMatch "soffice\.wasm\.gz$">
ForceType application/wasm
Header set Content-Encoding "gzip"
Header set Cross-Origin-Resource-Policy "cross-origin"
Header append Vary Accept-Encoding
</FilesMatch>
# Handle data.gz
<FilesMatch "soffice\.data\.gz$">
ForceType application/octet-stream
Header set Content-Encoding "gzip"
Header append Vary Accept-Encoding
</FilesMatch>
# ============================================
# 5. REDIRECTS & ROUTING
# ============================================
# Canonical WWW (update domain name)
RewriteCond %{HTTP_HOST} ^yourdomain\.com [NC]
RewriteRule ^(.*)$ https://www.yourdomain.com/$1 [L,R=301]
# Force HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [R=301,L]
# Existing files/dirs
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Language routes
RewriteRule ^(de|en)$ /$1/ [R=301,L]
RewriteRule ^(de|en|zh|vi)/(.*)$ /$2 [L]
# SPA Fallback
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ /index.html [L]
ErrorDocument 404 /index.html
```
## Subdirectory .htaccess Example
For `yourdomain.com/pdf-tools/`, update these lines:
```apache
RewriteBase /pdf-tools/
# ... (same content) ...
# SPA Fallback - update path
RewriteRule ^ /pdf-tools/index.html [L]
ErrorDocument 404 /pdf-tools/index.html
```
## Troubleshooting
### WASM Files Not Loading
Ensure the MIME types are correctly set in `.htaccess`:
```apache
AddType application/wasm .wasm
```
### LibreOffice Tools Not Working
The security headers are critical for SharedArrayBuffer:
```apache
Header always set Cross-Origin-Opener-Policy "same-origin"
Header always set Cross-Origin-Embedder-Policy "require-corp"
```
If headers aren't being applied, contact Hostinger support to enable `mod_headers`.
### 404 Errors on Page Refresh
Make sure the SPA fallback rule is at the end of your `.htaccess`:
```apache
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ /index.html [L]
```
### File Upload Limits
Hostinger may have file size limits. Upload WASM files separately if bulk upload fails.

View File

@@ -0,0 +1,96 @@
# Self-Hosting Guide
BentoPDF can be self-hosted on your own infrastructure. This guide covers various deployment options.
## Quick Start with Docker
The fastest way to self-host BentoPDF:
```bash
docker run -d -p 3000:80 ghcr.io/bentopdf/bentopdf:latest
```
Or with Docker Compose:
```yaml
# docker-compose.yml
version: '3.8'
services:
bentopdf:
image: ghcr.io/bentopdf/bentopdf:latest
ports:
- "3000:80"
restart: unless-stopped
```
```bash
docker compose up -d
```
## Building from Source
```bash
# Clone and build
git clone https://github.com/bentopdf/bentopdf.git
cd bentopdf
npm install
npm run build
# The built files are in the `dist` folder
```
## Configuration Options
### Simple Mode
Simple Mode is designed for internal organizational use where you want to hide all branding and marketing content, showing only the essential PDF tools.
**What Simple Mode hides:**
- Navigation bar
- Hero section with marketing content
- Features, FAQ, testimonials sections
- Footer
- Updates page title to "PDF Tools"
```bash
# Build with Simple Mode
SIMPLE_MODE=true npm run build
# Or use the pre-built Docker image
docker run -p 3000:8080 bentopdf/bentopdf-simple:latest
```
See [SIMPLE_MODE.md](https://github.com/bentopdf/bentopdf/blob/main/SIMPLE_MODE.md) for full details.
### Base URL
Deploy to a subdirectory:
```bash
BASE_URL=/pdf-tools/ npm run build
```
## Deployment Guides
Choose your platform:
- [Vercel](/self-hosting/vercel)
- [Netlify](/self-hosting/netlify)
- [Cloudflare Pages](/self-hosting/cloudflare)
- [AWS S3 + CloudFront](/self-hosting/aws)
- [Hostinger](/self-hosting/hostinger)
- [Nginx](/self-hosting/nginx)
- [Apache](/self-hosting/apache)
- [Docker](/self-hosting/docker)
## System Requirements
| Requirement | Minimum |
|-------------|---------|
| Storage | ~500 MB (with all WASM modules) |
| RAM | 512 MB |
| CPU | Any modern processor |
::: tip
BentoPDF is a static site—there's no database or backend server required!
:::

View File

@@ -0,0 +1,92 @@
# Deploy to Netlify
[Netlify](https://netlify.com) provides excellent static site hosting with a generous free tier.
## One-Click Deploy
[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/bentopdf/bentopdf)
## Manual Deployment
### Step 1: Connect Repository
1. Log in to [Netlify](https://app.netlify.com)
2. Click "Add new site" → "Import an existing project"
3. Connect your GitHub account
4. Select your BentoPDF fork
### Step 2: Configure Build Settings
| Setting | Value |
|---------|-------|
| Build command | `npm run build` |
| Publish directory | `dist` |
| Node version | 18+ |
### Step 3: Deploy
Click "Deploy site" and wait for the build.
## Configuration File
Create `netlify.toml` in your project root:
```toml
[build]
command = "npm run build"
publish = "dist"
[build.environment]
NODE_VERSION = "18"
# SPA routing
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
# Cache WASM files
[[headers]]
for = "*.wasm"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"
Content-Type = "application/wasm"
```
## Environment Variables
Set these in Site settings → Environment variables:
| Variable | Description |
|----------|-------------|
| `SIMPLE_MODE` | Set to `true` for minimal build |
## Custom Domain
1. Go to Site settings → Domain management
2. Click "Add custom domain"
3. Follow DNS configuration instructions
## Large Media
For large WASM files, consider enabling [Netlify Large Media](https://docs.netlify.com/large-media/overview/):
```bash
netlify lm:setup
git lfs track "*.wasm"
```
## Troubleshooting
### Build Fails
Check Node version compatibility:
```toml
[build.environment]
NODE_VERSION = "20"
```
### Slow Initial Load
Enable asset optimization in Site settings → Build & deploy → Asset optimization.

147
docs/self-hosting/nginx.md Normal file
View File

@@ -0,0 +1,147 @@
# Deploy with Nginx
Host BentoPDF on your own server using Nginx.
## Prerequisites
- Ubuntu/Debian server
- Nginx installed
- SSL certificate (recommended: Let's Encrypt)
## Step 1: Build the Project
```bash
git clone https://github.com/bentopdf/bentopdf.git
cd bentopdf
npm install
npm run build
```
## Step 2: Copy Files
```bash
sudo mkdir -p /var/www/bentopdf
sudo cp -r dist/* /var/www/bentopdf/
sudo chown -R www-data:www-data /var/www/bentopdf
```
## Step 3: Nginx Configuration
Create `/etc/nginx/sites-available/bentopdf`:
```nginx
server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
# SSL Configuration
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
root /var/www/bentopdf;
index index.html;
# Gzip compression
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/wasm;
gzip_min_length 1000;
# WASM MIME type
types {
application/wasm wasm;
}
# Cache static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|wasm)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# SPA routing - serve index.html for all routes
location / {
try_files $uri $uri/ /index.html;
}
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
}
```
## Step 4: Enable the Site
```bash
sudo ln -s /etc/nginx/sites-available/bentopdf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
```
## Step 5: SSL with Let's Encrypt
```bash
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.com
```
## Subdirectory Deployment
To host at `/pdf/`:
```nginx
location /pdf/ {
alias /var/www/bentopdf/;
try_files $uri $uri/ /pdf/index.html;
}
```
Build with:
```bash
BASE_URL=/pdf/ npm run build
```
## Performance Tuning
Add to `nginx.conf`:
```nginx
http {
# Enable sendfile
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# Increase buffer sizes
client_max_body_size 100M;
# Worker connections
worker_connections 2048;
}
```
## Troubleshooting
### WASM Not Loading
Ensure MIME type is set:
```nginx
types {
application/wasm wasm;
}
```
### 502 Bad Gateway
Check Nginx error logs:
```bash
sudo tail -f /var/log/nginx/error.log
```

View File

@@ -0,0 +1,75 @@
# Deploy to Vercel
[Vercel](https://vercel.com) offers the easiest deployment experience for static sites.
## One-Click Deploy
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/bentopdf/bentopdf)
## Manual Deployment
### Step 1: Fork the Repository
Fork [bentopdf/bentopdf](https://github.com/bentopdf/bentopdf) to your GitHub account.
### Step 2: Import to Vercel
1. Go to [vercel.com/new](https://vercel.com/new)
2. Select your forked repository
3. Configure the project:
| Setting | Value |
|---------|-------|
| Framework Preset | Vite |
| Build Command | `npm run build` |
| Output Directory | `dist` |
| Install Command | `npm install` |
### Step 3: Environment Variables (Optional)
Add these if needed:
```
SIMPLE_MODE=false
```
### Step 4: Deploy
Click "Deploy" and wait for the build to complete.
## Custom Domain
1. Go to your project settings
2. Navigate to "Domains"
3. Add your custom domain
4. Configure DNS as instructed
## Limitations
::: warning Large Files
Vercel's serverless functions have a 50MB limit. Since BentoPDF is a static site, this shouldn't affect you, but WASM modules are large (~100MB total). Ensure they're served from the `/public` folder.
:::
## Troubleshooting
### Build Timeout
If builds timeout, try:
```json
// vercel.json
{
"buildCommand": "npm run build",
"outputDirectory": "dist"
}
```
### 404 on Refresh
Add a `vercel.json` for SPA routing:
```json
{
"rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
}
```