/** * Configuration for the SEO Faster client */ interface SEOFasterConfig { /** Your SEO Faster API key (secret: cp_seof_sec_* for Next.js, public: cp_seof_pub_* for static sites) */ apiKey: string; /** Base URL for the API. Defaults to https://engine.seofaster.app */ baseUrl?: string; } /** * Featured image for an article */ interface FeaturedImage { url: string; alt?: string; } /** * FAQ item with question and answer */ interface FAQ { question: string; answer: string; } /** * Article content with markdown and optional HTML */ interface ArticleContent { /** Markdown content of the article */ markdown: string; /** HTML content (if available) */ html?: string; } /** * Article author information */ interface ArticleAuthor { name: string; title?: string; photo?: { url: string; alt?: string; }; } /** * Article returned from SEO Faster API */ interface Article { _id: string; title: string; slug: string; /** Article content in markdown/html format */ content: ArticleContent; metaDescription?: string; featuredImage?: FeaturedImage; faqs?: FAQ[]; author?: ArticleAuthor; seoScore?: number; locale?: string; status: 'draft' | 'published'; publishedAt?: string; createdAt: string; updatedAt: string; } /** * Response from getArticles API call */ interface ArticleListResponse { articles: Article[]; total: number; totalPages: number; page: number; limit: number; } /** * Slim article for card display (no HTML content) * Used by getRelatedArticles for better performance */ interface SlimArticle { _id: string; slug: string; title: string; metaDescription?: string; featuredImage?: FeaturedImage; publishedAt?: string; createdAt: string; locale?: string; category?: string; readingTime?: number; author?: { name: string; avatar?: string; }; } /** * Options for fetching related articles (slim payload) */ interface FetchRelatedArticlesOptions { /** Maximum number of articles to return. Defaults to 6, max 20 */ limit?: number; /** Filter by locale (e.g., 'en', 'es', 'fr') */ locale?: string; /** Exclude article with this slug (typically the current article) */ excludeSlug?: string; /** Next.js cache options for on-demand revalidation */ next?: NextCacheOptions; } /** * Next.js cache options for on-demand revalidation */ interface NextCacheOptions { /** Cache tags for selective revalidation via revalidateTag() */ tags?: string[]; /** Time-based revalidation in seconds */ revalidate?: number | false; } /** * Options for fetching articles */ interface FetchArticlesOptions { /** Page number (1-indexed). Defaults to 1 */ page?: number; /** Number of articles per page. Defaults to 10 */ limit?: number; /** Filter by locale (e.g., 'en', 'es', 'fr') */ locale?: string; /** Next.js cache options for on-demand revalidation */ next?: NextCacheOptions; } /** * Options for fetching a single article */ interface FetchArticleOptions { /** Filter by locale (e.g., 'en', 'es', 'fr') */ locale?: string; /** Next.js cache options for on-demand revalidation */ next?: NextCacheOptions; } /** * SEO Faster API client interface */ interface SEOFasterClient { /** * Fetch a list of published articles * @param options - Pagination, filter, and cache options * @returns Promise with articles array and pagination info */ getArticles(options?: FetchArticlesOptions): Promise; /** * Fetch a single article by its slug * @param slug - The article slug * @param options - Locale and cache options * @returns Promise with article or null if not found */ getArticleBySlug(slug: string, options?: FetchArticleOptions): Promise
; /** * Fetch related articles with slim payload (no HTML content) * Optimized for card display - ~90% smaller payload than getArticles * @param options - Filter and cache options * @returns Promise with slim articles array */ getRelatedArticles(options?: FetchRelatedArticlesOptions): Promise; } /** * Configuration for the cached client */ interface CachedClientConfig extends SEOFasterConfig { /** * Enable unstable_cache for cross-request persistence * @default true */ enableUnstableCache?: boolean; } /** * Cached client interface with dual-layer caching */ interface CachedClient { getArticleBySlug(slug: string, locale?: string): Promise
; getArticles(options?: FetchArticlesOptions): Promise; getRelatedArticles(options?: FetchRelatedArticlesOptions): Promise; _client: SEOFasterClient; } /** * Configuration for static params generator */ interface StaticParamsGeneratorConfig extends SEOFasterConfig { locales: string[]; fallbackLocale?: string; batchSize?: number; /** Delay in ms between paginated fetches (rate-limit cushion). Default 200. */ batchDelay?: number; maxPaginatedPages?: number; articlesPerPage?: number; /** * Generation mode (B.4): * 'full' — fetch all articles at build (default; pre-renders every slug) * 'empty' — return [] / empty maps synchronously; every page generates * on first visit and is then cached forever by Next.js ISR. * Pair with `dynamicParams: true` + `revalidate = false` on * the route. Build time drops to ~0 SEOFaster calls; first * visitor pays ~1s render, every subsequent visit hits the * cache. Webhooks invalidate per-article tags. */ mode?: 'full' | 'empty'; } /** * Result type for blog article static params */ interface BlogArticleParam { locale: string; slug: string; } /** * Result type for blog paginated static params */ interface BlogPaginatedParam { locale: string; page: string; } /** * Result type for blog list static params */ interface BlogListParam { locale: string; } /** * Static params generator result */ interface StaticParamsResult { blogArticle(): Promise; blogList(): Promise; blogPaginated(): Promise; getAllSlugs(): Promise>; _client: SEOFasterClient; _config: StaticParamsGeneratorConfig; } export type { Article as A, BlogArticleParam as B, CachedClientConfig as C, FetchArticlesOptions as F, SEOFasterConfig as S, SEOFasterClient as a, ArticleContent as b, ArticleAuthor as c, ArticleListResponse as d, FetchRelatedArticlesOptions as e, FeaturedImage as f, FAQ as g, SlimArticle as h, CachedClient as i, StaticParamsGeneratorConfig as j, StaticParamsResult as k, BlogPaginatedParam as l, BlogListParam as m };