seo-brief
SEO content-brief & keyword-planning microservice: turn a target keyword into a ready-to-write brief — a heading outline (H1/H2/H3), semantic entities to cover, People-Also-Ask style questions, a...
seo-brief — SEO content-brief & keyword-planning microservice
Turns a target keyword into everything you need before you write: an outline, semantic entities, People-Also-Ask questions, a target word count, internal-link ideas, title-tag and meta-description drafts, FAQ JSON-LD, content-gap analysis, and related/long-tail keyword expansion. A paid "intelligent microservice": every tool has a deterministic keyword-expansion + template core that runs fully offline, and the generative tools optionally call an LLM (via ../_shared/llm.js) to enrich, silently falling back. Every result is tagged mode: 'heuristic' | 'llm'.
Tools
| tool | output |
|---|---|
brief | keyword → outline (H1/H2/H3), entities, PAA questions, target word count, internal-link ideas, related keywords. |
titleTags | N SERP title tags within pixel-safe length (≤60 chars), brand-suffixed, intent-flavored. |
metaDescription | Meta descriptions within pixel-safe length (≤155 chars), keyword-front-loaded + CTA. |
faqSchema | FAQPage JSON-LD (schema.org) from {question,answer} pairs — or synthesized from the keyword — plus a ready <script> tag. |
contentGaps | Compares your draft text to the topic model → missing entities, questions, keywords + a coverage score. |
relatedKeywords | Expanded related / long-tail keyword list, each tagged with its own search intent. |
Intent is auto-detected (informational · commercial · transactional · navigational) or can be forced via intent. Word-count targets scale with intent.
Usage
import seoBrief from './index.js';
await seoBrief.adapters.brief({ keyword: 'email marketing', count: 8 });
await seoBrief.adapters.titleTags({ keyword: 'email marketing', brand: 'Leumas' });
seoBrief.adapters.faqSchema({ faqs: [{ question: 'What is X?', answer: 'X is …' }], url: 'https://ex.com/x' });
seoBrief.adapters.contentGaps({ keyword: 'email marketing', text: myDraft });
seoBrief.adapters.relatedKeywords({ keyword: 'email marketing', count: 20 });
Each call takes ONE args object (maps 1:1 to an HTTP POST body). brief/titleTags/metaDescription/ contentGaps/relatedKeywords require keyword; contentGaps also requires text; faqSchema requires either faqs or keyword. Missing inputs throw TypeError.
Hybrid intelligence
Templates + keyword expansion always produce output. When an LLM is reachable, brief (richer entities/questions via JSON), titleTags, and metaDescription enrich the result and keep the heuristic as fallback. A down/absent model never throws — the pack works 100% offline.
DRY boundary — distinct from seo
seoaudits content that already exists: it takes provided HTML/meta/text and analyzes it
(meta tags, OpenGraph, JSON-LD from a data payload, sitemap, keyword density, SERP preview).
seo-briefplans content that does not exist yet, starting from a keyword. Different input
(a keyword, not HTML) and a different job (planning vs. auditing). faqSchema here builds FAQPage JSON-LD for planning; seo.jsonLd still serves arbitrary schema from a data payload.
- No cross-pack imports except
../_shared/llm.js. Pure ESM, Node built-ins only, zero npm deps.