This commit is contained in:
118
README.md
Normal file
118
README.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# fast-website
|
||||
|
||||
Lightweight, SEO-first website for SanthoshJ that aggregates YouTube + Instagram + podcast content and tracks conversion events via Umami.
|
||||
|
||||
## Local Setup
|
||||
|
||||
```bash
|
||||
cd site
|
||||
cp .env.example .env
|
||||
npm install
|
||||
npm run fetch-content
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Open `http://localhost:4321`.
|
||||
|
||||
## Configuration
|
||||
|
||||
All configuration is via environment variables (see `site/.env.example`).
|
||||
|
||||
### YouTube
|
||||
|
||||
- `YOUTUBE_CHANNEL_ID` is required for ingestion.
|
||||
- Optional: `YOUTUBE_API_KEY` enables view-count ingestion for high-performing ranking.
|
||||
|
||||
Notes:
|
||||
- The channel ID looks like `UC...` and can be found by viewing the channel page source or via YouTube Studio settings.
|
||||
- If `YOUTUBE_API_KEY` is not set, ingestion falls back to the public channel RSS feed and metrics will be missing.
|
||||
|
||||
### Podcast
|
||||
|
||||
- `PODCAST_RSS_URL` is required to ingest episodes.
|
||||
|
||||
### Instagram (Embed-First)
|
||||
|
||||
Edit `site/content/instagram-posts.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"posts": [
|
||||
{ "url": "https://www.instagram.com/p/<id>/", "publishedAt": "2026-02-01T00:00:00Z", "title": "Movie post" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Phase 2 (API ingestion) path:
|
||||
- Requires Meta developer app setup, correct account type, token issuance + refresh, and platform policy compliance.
|
||||
- Recommended approach: keep embed-first for v1, then add an optional API ingest module when constraints are clear.
|
||||
|
||||
### Curation / Featured Videos
|
||||
|
||||
If YouTube metrics are not available, curate high-performing videos in `site/content/featured-videos.json`:
|
||||
|
||||
```json
|
||||
{ "videoIds": ["abc123", "def456"] }
|
||||
```
|
||||
|
||||
## Analytics (Umami)
|
||||
|
||||
Set:
|
||||
- `PUBLIC_UMAMI_SCRIPT_URL`
|
||||
- `PUBLIC_UMAMI_WEBSITE_ID`
|
||||
|
||||
If either is missing, analytics is disabled and the site still functions.
|
||||
|
||||
Event tracking is implemented using Umami's `data-umami-event` and `data-umami-event-*` attributes.
|
||||
|
||||
## Click Tracking Taxonomy (Umami-Compatible)
|
||||
|
||||
All tracked clickables MUST set:
|
||||
- `data-umami-event`: the event name (max 50 chars), e.g. `click`, `cta_click`, `outbound_click`
|
||||
- `data-umami-event-target_id`: stable unique identifier for the clickable element (namespaced like `nav.*`, `cta.*`, `card.*`)
|
||||
- `data-umami-event-placement`: where the clickable appears (e.g. `nav`, `hero`, `section_header`, `home.newest`)
|
||||
|
||||
For links, also set:
|
||||
- `data-umami-event-target_url`: destination URL (can be relative for internal navigation)
|
||||
|
||||
Common additional properties:
|
||||
- `data-umami-event-domain`: destination domain (for outbound links)
|
||||
- `data-umami-event-source`: `youtube` / `instagram` / `podcast` where applicable
|
||||
- `data-umami-event-ui_placement`: a sub-placement for UI grouping (e.g. `content_card`)
|
||||
|
||||
Instrumentation checklist:
|
||||
- Every clickable should have a unique `target_id` so it can be segmented in Umami.
|
||||
- Use categorical ids and placements only (no PII).
|
||||
|
||||
## Deployment (Linode + Docker)
|
||||
|
||||
Build and run:
|
||||
|
||||
```bash
|
||||
docker compose build
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
The container serves the static output on port `8080` (map or proxy as needed).
|
||||
|
||||
### Refreshing Content (Manual)
|
||||
|
||||
Content is fetched at build time into `site/content/cache/content.json`.
|
||||
|
||||
On the Linode host:
|
||||
|
||||
```bash
|
||||
./scripts/refresh.sh
|
||||
```
|
||||
|
||||
This:
|
||||
1. Runs `npm run fetch-content` in `site/`
|
||||
2. Rebuilds the Docker image
|
||||
3. Restarts the container
|
||||
|
||||
### Refreshing Content (Scheduled)
|
||||
|
||||
Install a daily cron using `deploy/cron.example` as a starting point.
|
||||
|
||||
Rollback:
|
||||
- Re-run `docker compose up -d` with a previously built image/tag, or restore the last known-good repo state and rerun `scripts/refresh.sh`.
|
||||
Reference in New Issue
Block a user