@econverse/faststore-blog-plugin
v0.1.12
Published
Rotas /blog e /blog/[slug] para lojas FastStore, com listagem e post individual alimentados pela REST API do WordPress (SEO via Yoast).
Readme
@econverse/faststore-blog-plugin
Plugin de rotas do FastStore que adiciona /blog (listagem) e /blog/[slug] (post) a uma storefront, buscando o conteúdo na REST API de um WordPress via wp-json/wp/v2 e usando o yoast_head_json para SEO.
Instalação
yarn add @econverse/faststore-blog-pluginConfiguração
1. discovery.config.js
module.exports = {
// ...
plugins: ['@econverse/faststore-blog-plugin'],
experimental: {
// ...
transpilePackages: ['@econverse/faststore-blog-plugin'],
},
}transpilePackages é obrigatório: o pacote distribui TypeScript/TSX fonte (não compilado), e o Next.js por padrão não transpila código dentro de node_modules.
2. Variável de ambiente
WORDPRESS_API_URL=https://seublog.com/wp-json/wp/v2Sem ela, qualquer chamada ao WordPress lança erro explícito em vez de silenciosamente falhar. Não é segredo — é só o endpoint público da REST API — então pode ir em vtex.env (WebOps) ou .env.local (dev).
3. Resolver GraphQL
O core do FastStore importa src/graphql/thirdParty/resolvers/index.ts por caminho fixo — esse arquivo não pode viver dentro do pacote. Ele fica no projeto consumidor e reexporta a lógica do pacote:
// src/graphql/thirdParty/resolvers/index.ts
import { getBlogPost, getBlogPosts } from '@econverse/faststore-blog-plugin/wordpress/service'
import type { BlogPost, BlogPostsResponse } from '@econverse/faststore-blog-plugin/wordpress/types'
const resolvers = {
Query: {
blogPosts: (_root: unknown, args: { page?: number | null; perPage?: number | null }): Promise<BlogPostsResponse> =>
getBlogPosts(args),
blogPost: (_root: unknown, { slug }: { slug: string }): Promise<BlogPost | null> =>
getBlogPost(slug),
},
}
export default resolversO typeDef GraphQL (BlogPost, BlogPostsResponse, Query.blogPosts/blogPost) também fica no projeto consumidor, em src/graphql/thirdParty/typeDefs/blog.graphql — é a definição do schema da loja, não faz parte do pacote.
O que o pacote resolve sozinho
- Fetch com timeout e cache TTL de 5 min por listagem/post (
src/wordpress/client.ts) - Normalização do post do WordPress pro formato exposto no GraphQL, incluindo SEO do Yoast (
src/wordpress/mapPost.ts) - Sanitização por allowlist do HTML do post antes de qualquer
dangerouslySetInnerHTML(src/utils/sanitizeBlogHtml.ts) — o WordPress é uma aplicação externa à storefront, então o conteúdo nunca chega cru ao cliente - Componentes de listagem (com paginação) e post individual, com SEO via
next-seo(src/components/BlogList,src/components/BlogPost) - Camada única de acesso (
src/wordpress/service.ts) compartilhada pelo resolver GraphQL e pelo SSR das páginas — evita dois caminhos de dados com comportamentos diferentes
Limitações conhecidas
- Cache em memória do processo (
Map), não distribuído — em ambientes com múltiplas instâncias cada uma tem seu próprio cache de 5 min. - Sanitização de HTML é por allowlist fixa de tags/atributos (ver
src/utils/sanitizeBlogHtml.ts) — conteúdo do WordPress usando tags fora da lista é desembrulhado (a tag some, o texto fica). - Espera que o WordPress tenha o plugin Yoast SEO instalado para os campos de SEO; sem ele,
seovemnulle o componente cai nos fallbacks (title/excerptdo próprio post).
