feat: prerender public site pages
This commit is contained in:
132
docs/SEO.md
Normal file
132
docs/SEO.md
Normal file
@@ -0,0 +1,132 @@
|
||||
# SEO And Public Page Prerendering
|
||||
|
||||
Socialize is primarily a client-side app, but the public marketing pages are prerendered during the frontend build so crawlers can index static HTML.
|
||||
|
||||
## Public Indexed Routes
|
||||
|
||||
These routes are treated as public site pages:
|
||||
|
||||
- `/`
|
||||
- `/product`
|
||||
- `/pricing`
|
||||
- `/blogs`
|
||||
- `/guides`
|
||||
|
||||
Authenticated app routes under `/app/*` and auth utility routes such as `/login`, `/register`, `/forgot-password`, `/reset-password`, and `/verify-email` are excluded from indexing in `robots.txt`.
|
||||
|
||||
## Build Flow
|
||||
|
||||
The frontend build runs:
|
||||
|
||||
```bash
|
||||
vite build
|
||||
vite build --ssr src/entry-public-ssr.js --outDir dist-ssr
|
||||
node scripts/prerender-public.mjs
|
||||
node scripts/write-public-seo.mjs
|
||||
```
|
||||
|
||||
This is wired into:
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
npm run build
|
||||
```
|
||||
|
||||
The prerender step writes static HTML files such as:
|
||||
|
||||
```txt
|
||||
frontend/dist/index.html
|
||||
frontend/dist/product/index.html
|
||||
frontend/dist/pricing/index.html
|
||||
frontend/dist/blogs/index.html
|
||||
frontend/dist/guides/index.html
|
||||
```
|
||||
|
||||
The SEO generator writes:
|
||||
|
||||
```txt
|
||||
frontend/dist/robots.txt
|
||||
frontend/dist/sitemap.xml
|
||||
```
|
||||
|
||||
## Production Domain
|
||||
|
||||
Set the public site URL when building for production:
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
VITE_PUBLIC_SITE_URL=https://your-domain.com npm run build
|
||||
```
|
||||
|
||||
This value is used for:
|
||||
|
||||
- canonical URLs
|
||||
- sitemap URLs
|
||||
- the sitemap reference in `robots.txt`
|
||||
|
||||
If `VITE_PUBLIC_SITE_URL` is not set, the build falls back to `SITE_URL`, then `http://localhost:5173`.
|
||||
|
||||
## Files To Update
|
||||
|
||||
When adding, removing, or renaming public indexed pages, update all of these:
|
||||
|
||||
- `frontend/src/router/router.js`
|
||||
- `frontend/src/entry-public-ssr.js`
|
||||
- `frontend/scripts/prerender-public.mjs`
|
||||
- `frontend/scripts/write-public-seo.mjs`
|
||||
- page metadata in the public page component via `usePublicPageMeta`
|
||||
|
||||
Public page metadata helper:
|
||||
|
||||
```txt
|
||||
frontend/src/features/landing/publicPageMeta.js
|
||||
```
|
||||
|
||||
## Server Routing
|
||||
|
||||
Caddy is configured to serve prerendered directory indexes before falling back to the SPA:
|
||||
|
||||
```txt
|
||||
try_files {path} {path}/index.html /index.html
|
||||
```
|
||||
|
||||
Config file:
|
||||
|
||||
```txt
|
||||
deploy/caddy/Caddyfile
|
||||
```
|
||||
|
||||
This matters because `/product` should serve `dist/product/index.html`, not the SPA fallback `dist/index.html`.
|
||||
|
||||
## Validation
|
||||
|
||||
After changes:
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
VITE_PUBLIC_SITE_URL=https://your-domain.com npm run build
|
||||
```
|
||||
|
||||
Check generated HTML:
|
||||
|
||||
```bash
|
||||
grep -n "<title>" dist/product/index.html
|
||||
grep -n "canonical" dist/product/index.html
|
||||
grep -n "Social media content approval" dist/product/index.html
|
||||
```
|
||||
|
||||
Check crawler files:
|
||||
|
||||
```bash
|
||||
cat dist/robots.txt
|
||||
cat dist/sitemap.xml
|
||||
```
|
||||
|
||||
## Search Engine Setup
|
||||
|
||||
After deployment:
|
||||
|
||||
1. Confirm public routes return `200`.
|
||||
2. Confirm `/robots.txt` and `/sitemap.xml` are served.
|
||||
3. Submit the sitemap in Google Search Console.
|
||||
4. Keep auth and app routes out of the sitemap unless they become public content.
|
||||
Reference in New Issue
Block a user