Next.js integration

Add a complete, AI-ready blog to your site.

Fetch only reviewed and published Frimma posts. Every item includes its image, accessible alt text, excerpt, tags, reading time, and canonical article URL.

1. Connect

Use your website domain in the public, read-only feed URL.

2. Create

Generate the article, SEO data, tags, and image direction from one brief.

3. Review & publish

Nothing appears in the feed until a human publishes the draft.

Install

One Server Component

Create app/blog/page.tsx, paste this component, and replace YOUR-DOMAIN.com. The five-minute revalidation keeps the page fast while new publications appear automatically.

type BlogPost = {
  slug: string;
  title: string;
  excerpt: string;
  image: string;
  imageAlt: string;
  publishedAt: string;
  category: string;
  tags: string[];
  readingTime: string;
  url: string;
};

async function getPosts(): Promise<BlogPost[]> {
  const response = await fetch(
    "https://frimma.com/api/blog/feed?site=YOUR-DOMAIN.com&limit=12",
    { next: { revalidate: 300 } },
  );

  if (!response.ok) throw new Error("Could not load blog posts");
  const data = await response.json();
  return data.items;
}

export default async function BlogPage() {
  const posts = await getPosts();

  return (
    <main>
      <h1>Latest articles</h1>
      <div className="blog-grid">
        {posts.map((post) => (
          <article key={post.slug}>
            <a href={post.url}>
              <img src={post.image} alt={post.imageAlt} />
              <p>{post.category} · {post.readingTime}</p>
              <h2>{post.title}</h2>
              <p>{post.excerpt}</p>
              <div>{post.tags.map((tag) => <span key={tag}>{tag}</span>)}</div>
            </a>
          </article>
        ))}
      </div>
    </main>
  );
}

Use a regular <img> for zero configuration, or add the Frimma image host to next.config.ts before switching to next/image. Style the three class names to match your site.

Automate the draft

Use structured generation so the result is valid before it reaches your CMS. Keep the generated item as a draft; validate facts, image rights, brand voice, and links before publication.

import { generateObject } from "ai";
import { z } from "zod";

const result = await generateObject({
  model: yourModel,
  schema: generatedBlogSchema,
  system: BLOG_AUTOMATION_SYSTEM_PROMPT,
  prompt: buildBlogAutomationPrompt({
    brand: "Your brand",
    website: "https://your-domain.com",
    audience: "The exact audience you want to help",
    topic: "The useful question this article answers",
    goal: "What the reader should understand or do next",
    language: "English",
  }),
});

// Save result.object as a draft. Publish it only after review.

Complete AI prompt

This is the production prompt Frimma uses for a complete article—not an outline. It returns the page copy, search metadata, image prompt, image alt text, tags, keywords, sections, and FAQ as JSON.

You are Frimma's senior editorial strategist and SEO editor.

Create a publication-ready blog post for the supplied brand, website, audience, goal, topic, and language. The article must be useful, specific, evidence-aware, and unmistakably aligned with the brand. Never invent customer stories, statistics, integrations, or product capabilities.

Return only valid JSON with this exact structure:
{
  "title": "clear benefit-led headline",
  "slug": "lowercase-kebab-case",
  "excerpt": "one compelling 40-320 character summary",
  "metaDescription": "80-170 character search description",
  "imagePrompt": "editorial hero image prompt with subject, composition, lighting, palette, aspect ratio 16:9, and no text or logos",
  "imageAlt": "accessible description of the intended image",
  "tags": ["3-10 reader-friendly tags"],
  "keywords": ["3-12 natural search phrases"],
  "sections": [
    {
      "id": "descriptive-anchor",
      "title": "section heading",
      "paragraphs": ["2-4 complete paragraphs"],
      "bullets": ["optional practical steps"]
    }
  ],
  "faq": [{ "question": "search-aware question", "answer": "concise answer" }]
}

Editorial requirements:
- Open with the reader's real problem, not a generic definition.
- Use a logical H2 structure and concrete, actionable guidance.
- Include at least one process, framework, or checklist.
- Use the primary keyword naturally; never keyword-stuff.
- Write self-contained paragraphs with no markdown or HTML.
- End with a useful conclusion and a restrained brand-relevant next step.
- The image prompt must be safe to send directly to an image model and must say “no text, no logos, no watermarks”.

Tested with Frimma

See the generated posts, images, metadata, and tags working together.