14 KiB
User Guide — WorkRoot Company Site
Complete guide for content management, environment setup, and troubleshooting.
Table of Contents
- Environment Setup
- Development Workflow
- Managing Blog Posts
- Updating Portfolio Items
- Available npm Scripts
- Troubleshooting Common Issues
1. Environment Setup
Prerequisites
| Requirement | Version |
|---|---|
| Node.js | 18.x or higher |
| npm | 8.x or higher |
Step 1: Install Dependencies
npm install
Step 2: Configure Environment Variables
Copy the example environment file and fill in your values:
cp .env.example .env
Open .env and configure the following:
Server Settings (Required)
HOST=0.0.0.0
PORT=10000
NODE_ENV=development
Contact Form Email (Required for contact form to work)
Uncomment and fill in your SMTP credentials. Gmail example:
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your_email@gmail.com
SMTP_PASS=your_app_password_here # Use App Password, not your regular password
CONTACT_EMAIL=hello@workroot.in # Where contact form submissions are sent
Gmail tip: Go to Google Account → Security → 2-Step Verification → App passwords to generate an App Password.
Newsletter Integration (Optional — pick one)
Option A: Mailchimp
MAILCHIMP_API_KEY=your_mailchimp_api_key
MAILCHIMP_LIST_ID=your_audience_list_id
MAILCHIMP_DC=us1
Option B: ConvertKit
CONVERTKIT_API_KEY=your_convertkit_api_key
CONVERTKIT_FORM_ID=your_form_id
Analytics (Optional — pick one)
Option A: Google Analytics 4
GOOGLE_ANALYTICS_ID=G-XXXXXXXXXX
Option B: Plausible (privacy-friendly)
PLAUSIBLE_DOMAIN=workroot.in
Error Monitoring (Optional but Recommended for Production)
SENTRY_DSN=https://xxx@oXXXXXX.ingest.sentry.io/XXXXXXX
LOG_LEVEL=info # Options: debug | info | warn | error
RELEASE_VERSION=1.0.0
Step 3: Start the Development Server
npm run dev
The site will be available at http://localhost:4321.
2. Development Workflow
Local Development
npm run dev # Start dev server with hot reload
npm run build # Build for production
npm run preview # Preview the production build locally
Production Server
npm run start:prod # Start the production Node.js server
The production server uses server.mjs which includes gzip/brotli compression and caching headers.
3. Managing Blog Posts
Blog posts are written in Markdown and stored in src/content/blog/. Each file is automatically turned into a page at /blog/[filename]/.
Creating a New Blog Post
- Create a new
.mdfile insrc/content/blog/:
src/content/blog/my-new-post.md
The filename becomes the URL slug. Use lowercase with hyphens: my-new-post.md → /blog/my-new-post.
- Add the required frontmatter at the top of the file:
---
title: "Your Post Title"
description: "A brief description for SEO and social sharing (150-160 characters recommended)."
pubDate: 2026-03-21
heroImage: "/images/blog/your-image.jpg"
category: "Web Development"
tags: ["Tag1", "Tag2", "Tag3"]
author:
name: "Author Name"
avatar: "/images/team/author.jpg"
draft: false
---
Your post content goes here...
- Write your content in Markdown below the frontmatter.
Frontmatter Reference
| Field | Type | Required | Description |
|---|---|---|---|
title |
string | Yes | Post title shown on the page |
description |
string | Yes | Meta description for SEO |
pubDate |
date | Yes | Publication date (YYYY-MM-DD) |
updatedDate |
date | No | Last updated date |
heroImage |
string | No | Path to hero image (e.g., /images/blog/image.jpg) |
category |
enum | Yes | Must be one of the valid categories (see below) |
tags |
string[] | Yes | Array of relevant tags |
author.name |
string | Yes | Author's display name |
author.avatar |
string | No | Path to author's avatar image |
draft |
boolean | No | Set to true to hide from listing (default: false) |
Valid Categories
The category field must be exactly one of these values:
Web DevelopmentMobile AppsAI/MLCloudDevOpsSecurity
Important: The value must match exactly (case-sensitive). Using an invalid category will cause a build error.
Working with Draft Posts
To write a post without publishing it:
draft: true
Draft posts won't appear in the blog listing but will still build. To publish, change draft: false or remove the field.
Adding Images to Blog Posts
-
Place your image in
public/images/blog/:public/images/blog/my-post-hero.jpg -
Reference it in the frontmatter:
heroImage: "/images/blog/my-post-hero.jpg" -
To embed images in the post body, use standard Markdown:

Updating an Existing Post
- Open the post's
.mdfile insrc/content/blog/ - Update the content and/or frontmatter
- Add or update
updatedDateto reflect when it was changed:updatedDate: 2026-03-21
Deleting a Blog Post
Simply delete the .md file from src/content/blog/. The route will no longer exist after the next build.
4. Updating Portfolio Items
Portfolio items are defined as JavaScript objects inside src/pages/portfolio.astro. There is no separate content folder for portfolio items.
Locating the Portfolio Data
Open src/pages/portfolio.astro and look for the array of project objects near the top of the file (inside the frontmatter --- block).
Adding a New Portfolio Item
Add a new object to the projects array:
{
id: 'my-new-project', // Unique ID, used for filtering. Use kebab-case.
title: 'My New Project',
category: 'web', // Must be: 'web', 'mobile', or 'ai'
thumbnail: '/images/portfolio/my-project.jpg',
description: 'Short 1-2 line description shown on the card.',
techStack: ['React', 'Node.js', 'PostgreSQL'],
client: 'Client Name',
duration: '3 months',
results: [
'50% reduction in load time',
'30% increase in user engagement',
],
fullDescription: 'Detailed paragraph describing the project, the challenge, and the solution. This appears in the expanded case study view.',
}
Portfolio Item Fields
| Field | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | Unique identifier. Use kebab-case (e.g., my-project). |
title |
string | Yes | Project name displayed on the card |
category |
string | Yes | Must be 'web', 'mobile', or 'ai' |
thumbnail |
string | Yes | Image path or URL for the project card |
description |
string | Yes | Short summary (1-2 sentences) |
techStack |
string[] | Yes | Technologies used (shown as badges) |
client |
string | Yes | Client or company name |
duration |
string | Yes | How long the project took (e.g., '6 months') |
results |
string[] | Yes | Key achievements/metrics (use 2-4 bullet points) |
fullDescription |
string | Yes | Detailed description for the case study view |
Valid Categories for Portfolio
| Category | Shows Up Under |
|---|---|
'web' |
"Web Development" filter |
'mobile' |
"Mobile Apps" filter |
'ai' |
"AI Solutions" filter |
Editing an Existing Portfolio Item
- Open
src/pages/portfolio.astro - Find the object with the matching
id - Update any fields you want to change
- Save the file — changes will appear immediately in dev mode
Removing a Portfolio Item
Delete the entire object { ... } from the projects array. Make sure to remove any trailing commas to keep valid JavaScript.
Using External Images (Unsplash, CDN, etc.)
You can use external image URLs directly in the thumbnail field:
thumbnail: 'https://images.unsplash.com/photo-1556742049-0cfed4f6a45d?w=600&h=400&fit=crop',
For local images, place them in public/images/portfolio/ and reference as /images/portfolio/filename.jpg.
5. Available npm Scripts
Development
| Command | Description |
|---|---|
npm run dev |
Start local development server (hot reload at localhost:4321) |
npm run build |
Build the site for production |
npm run preview |
Preview production build locally |
npm run start |
Start the standalone Node.js server |
npm run start:prod |
Start the server in production mode |
Testing
| Command | Description |
|---|---|
npm test |
Run all Playwright tests |
npm run test:smoke |
Quick smoke test (critical pages only) |
npm run test:critical |
Test critical user paths |
npm run test:api |
Test API endpoints |
npm run test:forms |
Test contact and newsletter forms |
npm run test:chromium |
Run tests in Chrome only |
npm run test:firefox |
Run tests in Firefox only |
npm run test:mobile |
Run mobile device tests |
npm run test:report |
Open the last test report in a browser |
npm run test:ci |
Run CI-appropriate subset of tests |
Backups
| Command | Description |
|---|---|
npm run backup:full |
Full site backup |
npm run backup:content |
Backup content files only |
npm run backup:config |
Backup configuration files |
npm run backup:list |
List available backups |
npm run backup:restore |
Restore from a backup |
npm run backup:verify |
Verify backup integrity |
npm run backup:cleanup |
Remove old backups |
Validation
| Command | Description |
|---|---|
npm run validate:schema |
Validate content schemas |
npm run validate:structured-data |
Validate JSON-LD structured data |
6. Troubleshooting Common Issues
Build fails with "Invalid frontmatter" error
Symptom: Running npm run build shows an error like Invalid value for field "category".
Cause: A blog post has an invalid or misspelled category value.
Fix: Open the failing .md file and ensure category is exactly one of:
Web Development | Mobile Apps | AI/ML | Cloud | DevOps | Security
Blog post not appearing on the site
Cause 1: The post has draft: true set.
Fix: Change to draft: false or remove the draft line.
Cause 2: The pubDate is in the future.
Fix: Set pubDate to today's date or earlier.
Cause 3: Missing required frontmatter fields.
Fix: Ensure title, description, pubDate, category, tags, and author.name are all present.
Contact form submissions not arriving
Cause: SMTP credentials are not configured or are incorrect.
Checklist:
- Confirm
.envhasSMTP_HOST,SMTP_PORT,SMTP_USER,SMTP_PASS, andCONTACT_EMAILset - If using Gmail, use an App Password (not your account password) — see Google App Passwords
- Check
LOG_LEVEL=debugin.envand restart the server to see detailed SMTP logs - Test the API directly:
curl -X POST http://localhost:10000/api/contact -H "Content-Type: application/json" -d '{"name":"Test","email":"test@example.com","message":"Hello"}'
Newsletter subscription not working
Cause: Newsletter provider credentials are missing or incorrect.
Checklist:
- Confirm the correct provider variables are set in
.env(Mailchimp OR ConvertKit, not both) - For Mailchimp: verify the
MAILCHIMP_DCmatches your API key's data center (the part after-in your API key, e.g.,us1) - For ConvertKit: confirm the
CONVERTKIT_FORM_IDis the numeric form ID, not the form name - Check server logs for error details
Dev server won't start (port conflict)
Symptom: Error: Port 4321 is already in use.
Fix:
# Find what's using the port
netstat -ano | findstr :4321 # Windows
lsof -i :4321 # Mac/Linux
# Or change the port in astro.config.mjs:
server: { port: 4322 }
Production server not starting
Symptom: npm run start:prod fails or crashes immediately.
Checklist:
- Run
npm run buildfirst — the server requires a production build indist/ - Confirm
NODE_ENV=productionin your.env - Check that
PORTis not blocked by a firewall - Review error output carefully — missing env variables often cause startup failures
Images not loading in production
Cause: Images placed in src/ instead of public/.
Fix: All static assets (images, fonts, etc.) must be in the public/ directory:
public/images/blog/my-image.jpg ✓
src/images/my-image.jpg ✗ (won't be served)
Analytics not tracking
Cause: GOOGLE_ANALYTICS_ID or PLAUSIBLE_DOMAIN not set, or the value uses the old Universal Analytics format.
Fix for GA4: The ID must start with G-, not UA-:
GOOGLE_ANALYTICS_ID=G-XXXXXXXXXX ✓
GOOGLE_ANALYTICS_ID=UA-XXXXXXXXX ✗ (old format, won't work)
After updating .env, rebuild and redeploy for changes to take effect.
Test suite failing locally
Symptom: Playwright tests fail with connection errors or timeout.
Fix:
- Ensure the dev/production server is running before tests
- Install Playwright browsers if first time:
npx playwright install - For API tests, ensure env variables are set
- Run a focused subset to isolate the issue:
npm run test:smoke
Validate structured data / schema errors
Symptom: npm run validate:structured-data shows errors.
Fix: Run the validator to see which pages have issues:
npm run validate:structured-data
Check the output for specific JSON-LD errors and fix the structured data in src/components/SEO.astro or the relevant page.
Additional Resources
| Resource | Location |
|---|---|
| Security audit & headers | SECURITY-AUDIT.md |
| SEO implementation details | SEO-IMPLEMENTATION.md |
| Performance baseline metrics | PERFORMANCE-BASELINE.md |
| Deployment instructions | DEPLOYMENT.md |
| Quick deployment reference | QUICK-DEPLOY.md |
| Changelog | CHANGELOG.md |
| Server setup | SERVER_README.md |
Last updated: 2026-03-21