Files
opencode-skill/skills/seo-multi-channel/scripts/templates/blog.yaml
Kunthawat Greethong 628298183a feat: migrate website-creator from Next.js+Payload to Astro+Tina CMS
Major changes:
- Replace Payload CMS with Tina CMS (self-hosted)
- Add Astro DB for consent logging (PDPA compliant)
- Update Tailwind v3 to v4 (@tailwindcss/vite plugin)
- Add astro-tina-starter template
- Rewrite consent template for Astro (ConsentBanner.astro, Astro DB, Nano Stores)
- Add install-tina-backend.sh for self-hosted Tina per customer
- Rename convert-astro.sh to migrate-tina.sh
- Add AGENTS.md template for generated websites
- Delete all Payload/Next.js files

Technical updates:
- Astro DB using defineDb with eq operators for queries
- Tailwind v4 with @theme block
- Tina CMS local development mode
- Proper Astro API routes for consent

Research-verified with official documentation (April 2026)
2026-04-17 14:52:59 +07:00

193 lines
3.9 KiB
YAML

# Blog SEO Article Template
channel: blog
priority: 4
language: [th, en]
# Article structure
structure:
min_word_count:
thai: 1500
english: 2000
max_word_count:
thai: 3000
english: 3000
keyword_density:
thai: 1.0-1.5%
english: 1.5-2.0%
sections:
- introduction:
word_count: 150-250
must_include:
- hook
- problem_statement
- promise
- primary_keyword_in_first_100_words
- body:
h2_sections: 4-7
h3_subsections: "as needed"
keyword_in_h2: "at least 2-3"
- conclusion:
word_count: 150-250
must_include:
- summary_of_key_points
- primary_keyword
- call_to_action
- cta_placement:
recommended_locations:
- after_first_value_section
- after_comparison_proof_section
- at_end
min_cta_count: 2
max_cta_count: 4
# Frontmatter requirements
frontmatter:
required_fields:
- title: 50-60 chars
- description: 150-160 chars (meta description)
- keywords: array of 5-10 keywords
- slug: url-friendly
- lang: th_or_en
- category: string
- tags: array of strings
- created: "YYYY-MM-DD"
- author: string_optional
optional_fields:
- updated: "YYYY-MM-DD"
- draft: boolean
- featured: boolean
- image:
src: path
alt: string
caption: string
# SEO requirements
seo:
meta_title:
min_chars: 50
max_chars: 60
must_include_primary_keyword: true
meta_description:
min_chars: 150
max_chars: 160
must_include_primary_keyword: true
must_include_cta: true
url_slug:
max_words: 5
format: "lowercase-with-hyphens"
include_primary_keyword: true
thai: "use_transliteration_or_keep_thai"
headings:
h1:
count: 1
include_primary_keyword: true
h2:
count: 4-7
include_keyword_variations: "2-3 minimum"
h3:
count: "as needed"
proper_nesting: true
internal_links:
min_count: 3
max_count: 7
anchor_text: "descriptive_with_keywords"
external_links:
min_count: 2
max_count: 4
authority_sources_only: true
images:
min_count: 2
max_count: 10
alt_text_required: true
descriptive_filenames: true
compressed: true
# Image handling for blog
images:
hero_image:
required: true
size: "1200x630"
location: "public/images/blog/{slug}/hero.png"
inline_images:
recommended_frequency: "every 300-400 words"
size: "800x600 or 1080x1080"
location: "public/images/blog/{slug}/"
generation:
for_product_content: "browse_repo_then_image_edit"
for_non_product: "image_generation"
# Content quality requirements
quality:
min_score: 70
checks:
- keyword_optimization
- brand_voice_alignment
- thai_formality_level
- readability_score
- factual_accuracy
- actionability
- originality
readability:
thai:
avg_sentence_length: "15-25 words"
grade_level: "ม.6-ม.12"
formality: "auto-detect_from_context"
english:
flesch_reading_ease: "60-70"
flesch_kincaid_grade: "8-10"
avg_sentence_length: "15-20 words"
# Output configuration
output:
format: markdown_with_frontmatter
encoding: "utf-8"
line_endings: "unix"
payload_cms_integration:
collection: "posts"
language_prefix:
thai: "th/"
english: ""
image_collection: "media"
publishing:
auto_publish: "optional (user_choice)"
git_commit: true
git_push: true
trigger_deploy: true
# API readiness (for future CMS integration)
api_ready:
cms_compatible:
- "WordPress"
- "Contentful"
- "Sanity"
- "Strapi"
schema_org:
type: "BlogPosting"
required_fields:
- headline
- description
- image
- datePublished
- author
- publisher