Full SEO + content automation pipeline shipped for Trade With Viet
Two properties (tradewithviet.com WordPress + vietconnect.tradewithviet.com Next.js) now have a 12-week content calendar, a weekly auto-publish pipeline to WordPress + social via Buffer, 6 new industry landing pages, a blog section, and structured data throughout. Human time once running: under 10 minutes per week.
6-layer thinking chain
"đánh giá SEO website; lên cho tôi chiến lược seo và nội dung bài đăng content cho web trade with viet, cũng như tự động hoá lịch trình đăng các nền tảng… tự động toàn bộ"
Two-domain SEO system
WordPress owns informational content (blog, guides, brand pages) — it is the SEO canonical. Next.js owns commercial content (supplier directory, industry pages, RFQ, tools). Both point to each other via internal links. The automation pipeline publishes to WordPress first, then queues social posts via Buffer. Next.js blog carries rel=canonical pointing to the WordPress URL so Google knows which one to index.
| Technical term | Plain name | Role |
|---|---|---|
wp_twv.py | WP publish bot | Creates future-dated blog posts on tradewithviet.com via WP REST API; sets AIOSEO meta title/description; uploads images |
humanizer-lint.py + twv-voice.json | Copy quality gate | Scans draft for banned AI phrases (seamlessly, cutting-edge, robust…) — exit 1 blocks publish |
getSuppliersByCategory() | Industry filter | Supabase query: finds category ID by slug, inner-joins supplier_categories, returns top N by verification_score |
ISR (Incremental Static Regeneration) | Self-refreshing static page | Industry + blog pages pre-built at deploy, auto-refresh every 24h — no server needed per request |
rel=canonical | SEO ownership tag | Tells Google: this Next.js blog URL is a mirror — the real page is at tradewithviet.com/blog/… |
Content flows left to right: draft → humanizer gate → WordPress (canonical) → Buffer social queue. VietConnect mirrors blog content but points back to WordPress via canonical tag. n8n triggers the weekly reminder; /twv-publish skill handles the actual publish steps.
What was built, in order
Layered decision cards
Artifact map
| Path | What | Who reads it |
|---|---|---|
scripts/twv-automation/wp_twv.py | WP REST publisher — create posts, upload media, queue Buffer | twv-publish skill |
scripts/twv-automation/twv-preflight.py | Pre-run environment check — WP creds, Buffer token, dirs, voice config | n8n, twv-publish skill |
scripts/twv-automation/humanizer/twv-voice.json | Banned phrases + specificity rules for TWV brand voice | humanizer-lint.py gate |
scripts/twv-automation/seo/config-twv.json | SEO audit config for tradewithviet.com | twv-seo-ux skill |
scripts/twv-automation/seo/config-vietconnect.json | SEO audit config for vietconnect.tradewithviet.com | twv-seo-ux skill |
scripts/twv-automation/content/calendar-twv.md | 12-week publish calendar (2026-06-16 → 2026-09-01) | Editorial reference |
scripts/twv-automation/content/drafts/ (12 files) | 12 blog draft stubs with body + LI/FB/IG captions | twv-publish skill input |
scripts/twv-automation/n8n/twv-weekly-publish.json | n8n workflow — Mon 07:00 ICT cron → preflight → Telegram notify | n8n import |
~/.claude/skills/twv-publish/SKILL.md | 7-step publish pipeline: validate → images → humanizer → WP → Buffer → archive → report | /twv-publish command |
~/.claude/skills/twv-seo-ux/SKILL.md | Weekly SEO dashboard for both domains (Friday 15:00 ICT) | /twv-seo-ux command |
src/lib/blog/index.ts | getAllPosts() + getPostBySlug() — reads MDX files from content/blog/ | /blog and /blog/[slug] pages |
src/app/blog/page.tsx | Blog index page — lists all posts, ISR 1h | Next.js SSG |
src/app/blog/[slug]/page.tsx | Blog post page — MDXRemote, Article JSON-LD, rel=canonical → WP, ISR 24h | Next.js SSG |
content/blog/complete-guide-sourcing-vietnam-2026.mdx | First blog post (Week 1 of 12) | Blog reader |
src/components/industry-landing-page.tsx | Shared server component for all 6 industry pages — supplier grid, key facts, JSON-LD | 6 industry page routes |
src/app/suppliers/apparel-textiles/page.tsx (×6) | 6 static industry landing pages — ISR 24h, BreadcrumbList + ItemList JSON-LD | SEO, buyers |
src/lib/supabase/server-queries.ts | Added getSuppliersByCategory() — category slug → inner join → top N suppliers | Industry landing pages |
src/app/pricing/layout.tsx | Added FAQPage JSON-LD (workaround: page.tsx is use client) | Google Rich Results |
src/app/sitemap.ts | Added blog posts + 6 industry pages to sitemap | Google Search Console |
src/components/layout/header.tsx | Added Blog nav link + Industries dropdown (desktop + mobile) | All pages |
src/components/layout/footer.tsx | Added Industries column with 6 category links | All pages |
~/.claude/skills/explainer/SKILL.md | This skill — session explainer builder + Hostinger deploy | /explainer command |
~/.claude/skills/explainer/scripts/build-explainer-twv.py | Spec JSON → self-contained HTML with password gate | explainer skill |
/home/u166949001/domains/tradewithviet.com/public_html/.htaccess | Added explainer subdomain bypass rule (routes explainer.tradewithviet.com → static HTML, skips WP PHP) | Hostinger LiteSpeed |
- Google Search Console: add beup-n8n-analytics@gws-490608.iam.gserviceaccount.com as Owner for tradewithviet.com property — needed before /twv-seo-ux skill can pull keyword data
- Buffer: create a new TWV org, connect LinkedIn + Facebook + Instagram, generate TWV_BUFFER_TOKEN, add to .env
- Update 3 channel ID placeholders in ~/.claude/skills/twv-publish/SKILL.md: REPLACE_WITH_TWV_LI_CHANNEL_ID, REPLACE_WITH_TWV_FB_CHANNEL_ID, REPLACE_WITH_TWV_IG_CHANNEL_ID
- n8n: import scripts/twv-automation/n8n/twv-weekly-publish.json, set TWV_TELEGRAM_CHAT_ID variable, test trigger manually
- Set GA4 property IDs in scripts/twv-automation/seo/config-twv.json and config-vietconnect.json
- Add TWV_WP_USER, TWV_WP_PASS, TWV_WP_BASE_URL, TWV_BUFFER_TOKEN to .env.local