socktop-webterm/STATIC_ASSETS.md

389 lines
8.0 KiB
Markdown
Raw Normal View History

# Adding Static Assets to webterm
## Overview
This guide explains how to add static assets (images, fonts, CSS files, etc.) to your webterm application.
## Directory Structure
```
webterm/
├── static/ # Your custom static assets
│ ├── bg.png # Background image
│ ├── terminado-addon.js
│ └── ... # Other custom files
├── node_modules/ # npm packages (served at /static)
│ ├── @xterm/
│ └── ...
└── templates/ # HTML templates
└── term.html
```
## How Static Files Are Served
The Rust backend serves static files from two locations:
1. **`/assets/*`** → serves from `./static/` directory
2. **`/static/*`** → serves from `./node_modules/` directory
### Configuration (src/server.rs)
```rust
let factory = || {
App::new()
.service(actix_files::Files::new("/assets", "./static"))
.service(actix_files::Files::new("/static", "./node_modules"))
// ... rest of config
};
```
## Adding a Background Image
### Step 1: Add the Image File
Place your image in the `static/` directory:
```bash
cp your-background.png static/bg.png
```
### Step 2: Reference in CSS
In `templates/term.html`, add CSS to use the image:
```html
<style>
body {
background-image: url('/assets/bg.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
background-attachment: fixed;
}
</style>
```
### Step 3: Test
```bash
cargo run
# Open http://localhost:8082/
# Check browser DevTools Network tab to verify /assets/bg.png loads
```
## Adding Other Static Assets
### Custom CSS File
**1. Create the file:**
```bash
echo "body { font-family: 'Custom Font'; }" > static/custom.css
```
**2. Reference in HTML:**
```html
<link rel="stylesheet" href="/assets/custom.css" />
```
### Custom JavaScript
**1. Create the file:**
```bash
echo "console.log('Custom script loaded');" > static/custom.js
```
**2. Reference in HTML:**
```html
<script src="/assets/custom.js"></script>
```
### Fonts
**1. Add font files:**
```bash
mkdir -p static/fonts
cp MyFont.woff2 static/fonts/
```
**2. Use in CSS:**
```css
@font-face {
font-family: 'MyFont';
src: url('/assets/fonts/MyFont.woff2') format('woff2');
}
body {
font-family: 'MyFont', sans-serif;
}
```
### Favicon
**1. Add favicon:**
```bash
cp favicon.ico static/
```
**2. Reference in HTML:**
```html
<link rel="icon" href="/assets/favicon.ico" type="image/x-icon" />
```
## Path Reference Guide
### From HTML Template (templates/term.html)
| Asset Location | URL Path | Example |
|----------------|----------|---------|
| `static/bg.png` | `/assets/bg.png` | `url('/assets/bg.png')` |
| `static/custom.css` | `/assets/custom.css` | `href="/assets/custom.css"` |
| `node_modules/@xterm/xterm/lib/xterm.js` | `/static/@xterm/xterm/lib/xterm.js` | Use `{{ static_path }}/@xterm/xterm/lib/xterm.js` |
### Template Variables
The HTML template has access to these variables:
- `{{ static_path }}` - Resolves to `/static` (for node_modules)
- `{{ websocket_path }}` - Resolves to `/websocket` (for WebSocket connection)
**Example:**
```html
<!-- npm packages use {{ static_path }} -->
<script src="{{ static_path }}/@xterm/xterm/lib/xterm.js"></script>
<!-- Custom assets use /assets directly -->
<img src="/assets/logo.png" alt="Logo" />
```
## Best Practices
### 1. Organize Your Assets
```
static/
├── images/
│ ├── bg.png
│ └── logo.png
├── fonts/
│ └── CustomFont.woff2
├── css/
│ └── custom.css
└── js/
├── terminado-addon.js
└── custom.js
```
### 2. Reference Images in CSS
Use relative paths or absolute paths from the `/assets` root:
```css
/* Good - absolute path */
background-image: url('/assets/images/bg.png');
/* Also good - for images in CSS files in static/css/ */
background-image: url('../images/bg.png');
```
### 3. Optimize Images
Before adding large images:
```bash
# Install optimization tools
sudo apt install optipng jpegoptim
# Optimize PNG
optipng -o7 static/bg.png
# Optimize JPEG
jpegoptim --size=500k static/photo.jpg
```
### 4. Use Appropriate File Formats
- **PNG**: Screenshots, logos, images with transparency
- **JPEG**: Photos, complex images
- **SVG**: Icons, logos, simple graphics
- **WebP**: Modern format, smaller file sizes (check browser support)
## Troubleshooting
### Image Returns 404
**Problem:** `/assets/bg.png` returns 404 Not Found
**Solutions:**
1. Check file exists:
```bash
ls -la static/bg.png
```
2. Verify server is running with updated code:
```bash
cargo build
cargo run
```
3. Check server logs for errors:
```bash
# Look for actix_files errors in console output
```
4. Test the URL directly:
```bash
curl -I http://localhost:8082/assets/bg.png
```
### Image Loads But Doesn't Display
**Problem:** Network tab shows 200 OK but image doesn't appear
**Solutions:**
1. Check CSS syntax:
```css
/* Wrong */
background: /assets/bg.png;
/* Correct */
background-image: url('/assets/bg.png');
```
2. Check image path in browser DevTools:
- Open DevTools → Elements
- Inspect the element with background
- Check computed styles
3. Verify image format is supported:
```bash
file static/bg.png
# Should show: PNG image data
```
### CORS Issues
If loading assets from different origins, you may need CORS headers.
**Add to src/server.rs:**
```rust
use actix_cors::Cors;
let factory = || {
App::new()
.wrap(
Cors::default()
.allow_any_origin()
.allow_any_method()
.allow_any_header()
)
.service(actix_files::Files::new("/assets", "./static"))
// ... rest of config
};
```
**Add to Cargo.toml:**
```toml
[dependencies]
actix-cors = "0.5"
```
## Performance Considerations
### Caching
For production, consider adding cache headers:
```rust
.service(
actix_files::Files::new("/assets", "./static")
.use_etag(true)
.use_last_modified(true)
)
```
### Compression
Enable gzip compression for text assets:
```rust
use actix_web::middleware::Compress;
let factory = || {
App::new()
.wrap(Compress::default())
.service(actix_files::Files::new("/assets", "./static"))
// ... rest
};
```
### CDN for Large Assets
For production websites, consider:
- Hosting large images on a CDN
- Using external image hosting (imgur, cloudinary, etc.)
- Optimizing and compressing all assets
## Example: Complete Background Setup
Here's a complete example adding a background image:
**1. Add the image:**
```bash
cp ~/my-background.png static/bg.png
```
**2. Update templates/term.html:**
```html
<style>
body {
background-image: url('/assets/bg.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
background-attachment: fixed;
/* Add overlay to improve text readability */
position: relative;
}
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5); /* Dark overlay */
z-index: -1;
}
</style>
```
**3. Run and test:**
```bash
cargo run
# Open http://localhost:8082/
```
## Summary
- Custom static files go in `./static/` directory
- Access them via `/assets/*` URLs
- npm packages are accessed via `/static/*` URLs
- Always rebuild and restart after changing Rust code
- Use browser DevTools to debug loading issues
- Optimize images before adding them
---
**Quick Reference:**
| I want to add... | Put it in... | Access it at... |
|------------------|--------------|-----------------|
| Background image | `static/bg.png` | `/assets/bg.png` |
| Custom CSS | `static/style.css` | `/assets/style.css` |
| Custom JS | `static/script.js` | `/assets/script.js` |
| Font file | `static/fonts/font.woff2` | `/assets/fonts/font.woff2` |
| Logo | `static/logo.png` | `/assets/logo.png` |