- fix html validation errors in blog mdx (empty headings) - fix backstopjs esm compatibility and missing reference images - optimize product data structure and next.config.mjs - finalize accessibility and seo improvements
KLZ Cables - Next.js Static Migration
A complete WordPress to Next.js static site migration for KLZ Cables, transforming a dynamic WordPress site into a high-performance static website.
🚀 Quick Start
Prerequisites
- Node.js 18+
- npm or yarn
Installation
# Install dependencies
npm install --legacy-peer-deps
# Set up environment variables
cp .env.example .env
# Edit .env with your API keys
# Run data export (if needed)
npm run data:export
npm run data:process
# Build the site
npm run build
# Export static files
npm run export
# Or run development server
npm run dev
### 🏗️ CMS (Strapi)
The CMS runs in Docker. Use the following npm scripts for local development:
```bash
# Start Strapi and its database
npm run cms:dev
# View logs
npm run cms:logs
# Stop the CMS
npm run cms:stop
Once running, you can access the Strapi admin panel at http://localhost:1337/admin.
🔄 Data & Migration
To sync data or migrate existing content:
# Export local data
npm run cms:export -- my-data.tar.gz
# Import data
npm run cms:import -- my-data.tar.gz
# Migrate existing MDX data to Strapi
npm run cms:migrate
Environment Variables
# .env
SITE_URL=https://klz-cables.com
RESEND_API_KEY=your_resend_key
TURNSTILE_SITE_KEY=your_turnstile_key
TURNSTILE_SECRET_KEY=your_turnstile_secret
# Umami
UMAMI_WEBSITE_ID=your_umami_website_id
UMAMI_API_ENDPOINT=https://analytics.infra.mintel.me
# GlitchTip (Sentry compatible)
SENTRY_DSN=https://PUBLIC_KEY@errors.infra.mintel.me/PROJECT_ID
NEXT_PUBLIC_SENTRY_DSN=https://PUBLIC_KEY@errors.infra.mintel.me/PROJECT_ID
📊 Project Overview
Migration Statistics
- Content Exported: 141 items
- 18 pages (9 EN + 9 DE)
- 59 posts (29 EN + 30 DE)
- 50 products (25 EN + 25 DE)
- 14 categories (7 EN + 7 DE)
- Media Files: 50 images
- Redirects: 59 rules
- Translation Pairs: 16
Performance Benefits
- Before: Dynamic WordPress with database queries
- After: Static HTML with CDN delivery
- Load Time: <100ms (vs 500ms+)
- Hosting Cost: ~90% reduction
🏗️ Architecture
Tech Stack
- Framework: Next.js 14 (App Router)
- Language: TypeScript
- Styling: SCSS
- CMS: Strapi (Source of Truth)
- Data: Static JSON (WordPress export) & Strapi API
- Email: Resend
- Analytics: Vercel (consent-based)
- CAPTCHA: Cloudflare Turnstile
Project Structure
app/
├── layout.tsx # Root layout
├── page.tsx # Home (EN)
├── globals.scss # Global styles
├── blog/
│ ├── page.tsx # Blog index
│ └── [slug]/page.tsx # Blog post
├── products/
│ ├── page.tsx # Products index
│ └── [slug]/page.tsx # Product detail
├── product-category/
│ └── [slug]/page.tsx # Category page
├── contact/
│ └── page.tsx # Contact form
├── de/ # German pages
│ ├── page.tsx
│ ├── blog/
│ ├── products/
│ ├── product-category/
│ └── contact/
├── api/
│ └── contact/route.ts # Contact API
├── sitemap.ts # Sitemap generator
├── robots.ts # Robots.txt generator
lib/
├── data.ts # Data access
├── i18n.ts # Internationalization
└── html-compat.ts # WPBakery compatibility
components/
├── LocaleSwitcher.tsx # Language switcher
├── ContactForm.tsx # Contact form
├── CookieConsent.tsx # GDPR banner
├── SEO.tsx # SEO utilities
data/
├── raw/ # WordPress export
└── processed/ # Next.js data
public/
└── media/ # Downloaded images
scripts/
├── wordpress-export.js # Export tool
├── process-data.js # Data processor
├── analyze-export.js # Analyzer
└── improve-translation-mapping.js # Translation mapper
🎯 Features
✅ Implemented
- Multi-language: EN/DE with
/de/prefix routing - Contact Forms: Resend integration with validation
- GDPR Compliance: Cookie consent banner
- SEO: hreflang, canonical, Open Graph, Twitter cards
- Sitemap: Dynamic sitemap generation
- Robots.txt: Dynamic robots.txt
- WPBakery Compatibility: HTML sanitization
- Static Generation: All pages pre-rendered
- Translation Mapping: Cross-language references
- Asset Management: WordPress → local path mapping
🔄 In Progress
- Analytics integration (consent-based)
- Turnstile CAPTCHA
- Build testing
- Deployment configuration
📝 Remaining
- Performance optimization
- Final QA testing
- Documentation updates
📝 Content Management
Data Export
# Export from WordPress
npm run data:export
# Process for Next.js
npm run data:process
# Analyze export
npm run data:analyze
# Improve translation mapping
npm run data:improve-mapping
Adding New Content
- Export new content from WordPress
- Process the data
- Rebuild the site
🎨 Design System
Colors
- Primary:
#0066cc(KLZ Blue) - Secondary:
#00a896(Teal) - Text:
#1a1a1a - Background:
#f8f9fa
Typography
- Font: Inter
- Base: 16px
- Scale: 1.25 (Major Third)
Layout
- Max width: 1200px
- Responsive grid
- Mobile-first
🔧 API Endpoints
Contact Form
POST /api/contact
{
"name": "John Doe",
"email": "john@example.com",
"message": "Hello!",
"locale": "en"
}
Sitemap
GET /sitemap.xml
Robots
GET /robots.txt
🚀 Deployment
Automatic Deployment (Current Setup)
The project uses Gitea Actions for CI/CD. Every push to main or staging triggers:
- Build: Docker image built for
linux/arm64with branch-specific build args - Push: Image pushed to
registry.infra.mintel.mewith commit SHA tag - Deploy: SSH to production server, pull and restart containers using branch-specific
.envfiles
Workflow: .gitea/workflows/deploy.yml
Branch Deployments:
mainbranch: Deploys to production using.env.prodstagingbranch: Deploys to staging using.env.staging
Environment Overrides:
The CI/CD workflow supports STAGING_-prefixed secrets (e.g., STAGING_NEXT_PUBLIC_BASE_URL) to override default secrets when deploying the staging branch.
Required Secrets (configure in Gitea repository settings):
REGISTRY_USER- Docker registry usernameREGISTRY_PASS- Docker registry passwordALPHA_SSH_KEY- SSH private key for deploymentNEXT_PUBLIC_BASE_URL- Application base URL (e.g.,https://klz-cables.com)UMAMI_WEBSITE_ID- Analytics IDUMAMI_API_ENDPOINT- Analytics API endpoint (formerly NEXT_PUBLIC_UMAMI_SCRIPT_URL)SENTRY_DSN- Error tracking DSNMAIL_HOST,MAIL_PORT,MAIL_USERNAME,MAIL_PASSWORD,MAIL_FROM,MAIL_RECIPIENTS- Email configuration
Manual Deployment
# SSH into production server
ssh deploy@alpha.mintel.me
# Navigate to project
cd /home/deploy/sites/klz-cables.com
# Pull latest image and restart
docker compose pull
docker compose up -d --force-recreate --remove-orphans
docker image prune -f
Or use the convenience script:
bash scripts/deploy-webhook.sh
Architecture
Client → Traefik (TLS) → Next.js App
Domains:
klz-cables.com- Productionwww.klz-cables.com- Production (www)staging.klz-cables.com- Staging
Services:
app: Next.js application (port 3000)traefik: Reverse proxy (external)
For detailed deployment documentation, see docs/DEPLOYMENT.md.
📈 Performance
Build Time
- Target: < 2 minutes
- Current: ~1-2 minutes
Page Load
- Target: < 100ms
- Current: Static HTML from CDN
Bundle Size
- Target: < 100KB gzipped
- Current: Optimized with code splitting
🔒 Security
Environment Variables
- Never commit
.envfile - Rotate keys regularly
- Use secrets in deployment platform
Form Security
- Email validation
- Rate limiting (recommended)
- Turnstile CAPTCHA (pending)
🎓 WordPress Specifics
WPBakery Shortcodes Removed
[vc_row],[vc_column],[vc_column_text][nectar_*](Salient theme)[image_with_animation][split_line_heading][divider]
HTML Sanitization
- Removes inline event handlers
- Strips scripts
- Normalizes classes
- Preserves structure
Asset Mapping
WordPress URLs → Local paths:
https://klz-cables.com/wp-content/uploads/... → /media/...
📚 Documentation
Internal
PROJECT_STRUCTURE.md- Detailed structureIMPLEMENTATION_SUMMARY.md- Progress trackingFINAL_SUMMARY.md- Complete overview
External
🐛 Troubleshooting
Common Issues
TypeScript Errors
- The TypeScript errors shown in the editor are expected
- They occur because modules reference each other
- The build process resolves these correctly
- Run
npm run buildto verify
Build Failures
- Check environment variables
- Verify data files exist
- Clear
.nextcache:rm -rf .next
Missing Modules
- Run
npm install --legacy-peer-deps - Check
package.jsondependencies
🎯 Success Criteria
✅ Data Export: All WordPress content extracted
✅ Processing: Data transformed for Next.js
✅ Structure: Complete project setup
✅ Components: Core UI components built
✅ Pages: All required pages created
✅ API: Contact form working
✅ i18n: Multi-language support
✅ SEO: Metadata and sitemaps
✅ Compatibility: WPBakery content handled
✅ Media: All images downloaded
📞 Support
For issues or questions:
- Check the documentation
- Review the troubleshooting section
- Check environment variables
- Verify data export completeness
📄 License
Proprietary - KLZ Cables
Status: ✅ READY FOR DEPLOYMENT
Version: 1.0.0
Last Updated: December 27, 2025