> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rocket.new/llms.txt
> Use this file to discover all available pages before exploring further.

# Build a content site

> Recipe for building a modern content site in Rocket.new with blog posts, categories, author pages, SEO metadata, and a headless CMS integration.

export const LlmsDirective = () => <blockquote className="llms-directive">
    For the complete documentation index, see <a href="/llms.txt">llms.txt</a>.
    For a lightweight markdown version of this page, append .md to the URL.
  </blockquote>;

<LlmsDirective />

<Info>
  A modern content site and blog where editors create and manage articles through a headless CMS, readers browse posts by category, and each author has a dedicated profile page. The finished product includes full SEO metadata, a newsletter signup form, site-wide search, analytics tracking, and one-click deployment to Netlify.

  By the end of this recipe you will have a production-ready blog that you can customize, rebrand, and launch as your own publication.
</Info>

## Tech stack

<Note>You do not need to understand these technologies. Rocket handles them automatically. This table is for reference.</Note>

| Service                  | Role                                                                |
| ------------------------ | ------------------------------------------------------------------- |
| **Next.js + TypeScript** | Frontend framework with static generation and server-side rendering |
| **Strapi**               | Headless CMS for managing articles, categories, and authors         |
| **Supabase**             | Comment system, newsletter subscribers, and user data               |
| **Google Analytics**     | Traffic analytics, page views, and audience insights                |
| **Netlify**              | Production deployment, hosting, and CDN                             |

## Architecture overview

Here is how the pieces connect:

1. An editor creates a new article in **Strapi**, assigning a category, author, featured image, and SEO metadata.
2. When the article is published, the **Next.js** frontend fetches the content from the Strapi API and renders it as a static page.
3. Readers can **browse by category** or use the **search bar** to find articles by title or keyword.
4. Each article page includes an **author card** that links to the author's profile, showing their bio and all published posts.
5. Readers can **subscribe to the newsletter** via a signup form powered by Supabase. Subscriber data is stored securely for future email campaigns.
6. **Google Analytics** tracks page views, popular articles, and reader engagement across the site.
7. The entire site is **deployed to Netlify** with automatic rebuilds triggered by CMS content changes.

## How long does it take?

| Phase     | What you are building         | Estimated time    |
| --------- | ----------------------------- | ----------------- |
| Setup     | Project, Strapi CMS           | 5-10 minutes      |
| Content   | Articles, categories, authors | 10-15 minutes     |
| Features  | Search, newsletter            | 5-10 minutes      |
| Launch    | Analytics, deploy             | 5 minutes         |
| **Total** | **Complete content site**     | **25-40 minutes** |

## Step-by-step build

<Steps>
  <Step title="Start a new project">
    Open [rocket.new](https://rocket.new) and create a new project. Give Rocket a detailed description of the blog so it scaffolds the right pages, layout, and navigation from the start.

    ```plaintext wrap theme={null}
    Build a modern blog called "The Daily Byte" using Next.js and TypeScript. Include these pages: homepage with hero section and featured articles grid, article listing page with category filters, individual article page with rich text content and author bio, author profile page listing all their posts, about page, and a contact page. Use a clean, modern design with a serif font for headings and a sans-serif font for body text. Add a responsive navbar with logo, navigation links, and a search icon. Include a footer with newsletter signup and social media links.
    ```

    <Tip>
      Be specific about the pages and layout you want in your first prompt. The more detail you give, the less back-and-forth you will need later.
    </Tip>
  </Step>

  <Step title="Connect Strapi as your CMS">
    Go to **Integrations** in your Rocket project and connect your Strapi instance. Then ask Rocket to set up the content types and connect them to the frontend.

    ```plaintext wrap theme={null}
    Connect Strapi and create the following content types:
    1. "Article" - title (text), slug (uid based on title), content (rich text), excerpt (text), featured_image (media), category (relation to Category), author (relation to Author), published_date (date), seo_title (text), seo_description (text), is_featured (boolean)
    2. "Category" - name (text), slug (uid based on name), description (text), color (text for hex code)
    3. "Author" - name (text), slug (uid based on name), bio (rich text), avatar (media), twitter_handle (text), website_url (text)
    Fetch articles from Strapi on the homepage and article listing pages. Use static generation (getStaticProps) for fast page loads with incremental static regeneration so new articles appear without a full rebuild.
    ```

    <Info>
      Rocket handles the Strapi connection through the integrations panel. Your API URL and tokens are encrypted and stored securely, so you never need to copy them manually.
    </Info>
  </Step>

  <Step title="Build article pages">
    Now create the individual article pages with rich content rendering, author attribution, and SEO metadata.

    ```plaintext wrap theme={null}
    Build the article detail page at /articles/[slug]:
    - Fetch the full article from Strapi by slug
    - Render the rich text content with proper formatting for headings, paragraphs, lists, images, code blocks, and blockquotes
    - Show the article title, published date, category badge, and reading time estimate at the top
    - Display the featured image as a hero banner
    - Add an author card at the bottom with avatar, name, bio snippet, and a link to their full profile page
    - Add SEO metadata using Next.js Head: page title, meta description, Open Graph image, and Twitter card tags
    - Add structured data (JSON-LD) for Article schema to help with search engine indexing
    ```
  </Step>

  <Step title="Add categories and author pages">
    Build the category filter system and dedicated author profile pages so readers can explore content by topic or writer.

    ```plaintext wrap theme={null}
    Add category and author pages:
    - Create a category page at /categories/[slug] that lists all articles in that category with the category name, description, and a colored header matching the category's hex color
    - Add category filter buttons on the main articles listing page that filter without a full page reload
    - Create an author profile page at /authors/[slug] showing the author's avatar, full bio, website link, Twitter handle, and a grid of all their published articles sorted by date
    - Add an "All Authors" page at /authors listing every author with their avatar, name, article count, and a link to their profile
    ```
  </Step>

  <Step title="Add search functionality">
    Let readers find articles quickly with a site-wide search feature.

    ```plaintext wrap theme={null}
    Add a search feature to the blog:
    - Add a search icon in the navbar that opens a search modal overlay
    - The search modal should have an auto-focused text input with a clean, minimal design
    - Search articles by title, excerpt, and content using the Strapi search API or a client-side search index
    - Show results as a list with article title, excerpt preview, category badge, and published date
    - Highlight the matching text in the results
    - Support keyboard navigation: arrow keys to move between results, Enter to open an article, and Escape to close the modal
    - Show "No results found" with suggested categories when the query does not match any articles
    ```

    <Tip>
      For small to medium blogs (under 500 articles), client-side search with a library like Fuse.js is fast and simple. For larger sites, consider connecting Algolia or Meilisearch for server-side search.
    </Tip>
  </Step>

  <Step title="Add newsletter signup">
    Add a newsletter subscription form so readers can sign up for updates. Store subscribers in Supabase for future email campaigns.

    ```plaintext wrap theme={null}
    Connect Supabase and add newsletter functionality:
    - Create a "subscribers" table in Supabase with: id (uuid), email (text, unique), name (text, optional), subscribed_at (timestamp), is_active (boolean, default true)
    - Add a newsletter signup form in the site footer with an email input and a "Subscribe" button
    - Add a larger newsletter signup section at the bottom of each article page with a heading like "Stay in the loop" and a brief description
    - Show a success message after subscribing and handle duplicate emails gracefully with a friendly message
    - Add row-level security so subscribers cannot read other subscribers' data
    - Add a simple admin API route to export the subscriber list as CSV
    ```

    <Info>
      You can later connect a service like Mailchimp, Brevo, or Resend to send automated email campaigns to your subscriber list.
    </Info>
  </Step>

  <Step title="Set up analytics">
    Connect Google Analytics to track page views, popular articles, and reader behavior.

    ```plaintext wrap theme={null}
    Connect Google Analytics (GA4) and add tracking:
    - Add the GA4 measurement script to the site
    - Track page views automatically on every route change
    - Add custom events for: article_view (with article title and category), newsletter_signup, search_performed (with search query), author_profile_view, and category_filter_used
    - Set up content grouping by category so you can see which topics drive the most traffic
    - Add UTM parameter tracking for measuring social media and email campaign performance
    ```
  </Step>

  <Step title="Deploy to Netlify">
    Go to **Integrations** and connect Netlify, then deploy your blog to the web.

    Use the **Launch** button in your Rocket project to deploy to the web. Rocket handles the Netlify build configuration automatically. Make sure all required environment variables are set in your project's integration settings before launching.

    <Tip>
      After deploying, set up a Strapi webhook pointing to the Netlify build hook URL. This way your site automatically rebuilds whenever you publish or update an article in the CMS.
    </Tip>
  </Step>
</Steps>

## Customization ideas

Once the base blog is running, here are ways to extend it.

<AccordionGroup>
  <Accordion title="Add a comment system" icon="comments">
    Let readers leave comments on articles. Use Supabase to store comments with moderation support so you can approve or remove comments before they appear.

    ```plaintext wrap theme={null}
    Add a comment section to each article page. Create a "comments" table in Supabase with article_slug, author_name, content, created_at, and is_approved fields. Show approved comments below the article. Add a comment form with name and message fields. New comments default to unapproved so you can moderate them from an admin page.
    ```
  </Accordion>

  <Accordion title="Add dark mode" icon="moon">
    Give readers the option to switch between light and dark themes. Persist the preference in localStorage so it carries across visits.

    ```plaintext wrap theme={null}
    Add a dark mode toggle to the navbar. Implement a theme provider that switches between light and dark color schemes. Use CSS variables for all colors so the switch is seamless. Default to the system preference, and save the user's choice in localStorage. Make sure all pages, components, and the newsletter form look correct in both modes.
    ```
  </Accordion>

  <Accordion title="Add an RSS feed" icon="rss">
    Generate an RSS feed so readers can subscribe using their favorite feed reader and get notified about new articles automatically.

    ```plaintext wrap theme={null}
    Generate an RSS 2.0 feed at /rss.xml that includes the 20 most recent articles. Each item should have the title, link, publication date, author, category, and the excerpt as the description. Add an Atom feed at /atom.xml as well. Include a link to the RSS feed in the site header meta tags and in the footer.
    ```
  </Accordion>

  <Accordion title="Add social sharing buttons" icon="share-nodes">
    Make it easy for readers to share articles on social media with one-click share buttons.

    ```plaintext wrap theme={null}
    Add social sharing buttons to each article page, positioned below the title and at the bottom of the article. Include buttons for Twitter, LinkedIn, Facebook, and a "Copy Link" button. Pre-fill the share text with the article title and URL. Use native share dialogs on mobile with the Web Share API where supported.
    ```
  </Accordion>

  <Accordion title="Add related posts" icon="layer-group">
    Show related articles at the end of each post to keep readers engaged and reduce bounce rate.

    ```plaintext wrap theme={null}
    Add a "Related Articles" section at the bottom of each article page, above the comments. Show 3 related articles based on the same category. If there are fewer than 3 articles in the same category, fill the remaining slots with the most recent articles from other categories. Display each related article as a card with the featured image, title, excerpt, and published date.
    ```
  </Accordion>
</AccordionGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Articles are not showing up on the site">
    If the blog loads but articles are missing, the Strapi connection may need attention. First, make sure your articles are set to **Published** (not Draft) in Strapi. Then ask Rocket to debug:

    ```plaintext wrap theme={null}
    The blog is loading but no articles are appearing. Review the code that fetches articles from the Strapi API and make sure the endpoint URL, content type name, and response parsing are correct. Remind me to verify that the API permissions in the Strapi dashboard allow public read access.
    ```
  </Accordion>

  <Accordion title="Images loading slowly or not displaying">
    If featured images are broken or slow, ask Rocket to optimize the image handling:

    ```plaintext wrap theme={null}
    Featured images are loading slowly or showing as broken. Optimize the image setup by using the Next.js Image component with proper configuration for my Strapi media URLs. Add lazy loading, modern image formats, and blurred placeholders for large images.
    ```
  </Accordion>

  <Accordion title="Shared links show a generic preview instead of article details">
    If sharing a link on social media shows a generic title instead of the article's own title and image, the SEO metadata may be missing. Ask Rocket to fix it:

    ```plaintext wrap theme={null}
    When I share an article link on social media, it shows a generic preview instead of the article title and image. Add proper Open Graph and Twitter Card meta tags to each article page using the article's title, description, and featured image so social previews look correct.
    ```

    After Rocket updates the code, you can test your links with the [Facebook Sharing Debugger](https://developers.facebook.com/tools/debug/) to verify the preview.
  </Accordion>
</AccordionGroup>
