Static Site Generators

Integrate FlareBuilder with Next.js, Gatsby, Hugo, Jekyll, and Astro

Overview

Static site generators can fetch content from FlareBuilder at build time or render time. This guide covers the most popular frameworks.

Build-time vs Runtime:
Build-time (SSG): Fetch content during build, bundle it into static HTML
Runtime (CSR): Load the FlareBuilder SDK in the browser, fetch content dynamically

Next.js

Next.js supports both server-side rendering (SSR) and static generation (SSG). Here's how to fetch FlareBuilder content at build time:

Static Generation (Recommended)

// pages/feed.js or app/feed/page.js
export async function getStaticProps() {
  const res = await fetch('https://your-tenant.flarebuilder.com/api/feed?limit=10');
  const data = await res.json();

  return {
    props: {
      feed: data.items
    },
    revalidate: 300 // Revalidate every 5 minutes
  };
}

export default function FeedPage({ feed }) {
  return (
    <div>
      <h1>Our Content</h1>
      {feed.map(item => (
        <article key={item.id}>
          <h2>{item.title}</h2>
          {item.tags && (
            <div className="tags">
              {item.tags.map(tag => (
                <span key={tag} className="tag">{tag}</span>
              ))}
            </div>
          )}
          {item.sections && Object.entries(item.sections).map(([sectionId, fields]) => (
            <div key={sectionId}>
              {Object.entries(fields).map(([fieldId, value]) => {
                if (fieldId === 'image' && value) {
                  return <img key={fieldId} src={value} alt="" />;
                }
                if (fieldId === 'content_html' && value) {
                  return <div key={fieldId} dangerouslySetInnerHTML={{ __html: value }} />;
                }
                return null;
              })}
            </div>
          ))}
        </article>
      ))}
    </div>
  );
}

App Router (Next.js 13+)

// app/feed/page.tsx
async function getFeed() {
  const res = await fetch('https://your-tenant.flarebuilder.com/api/feed?limit=10', {
    next: { revalidate: 300 } // Cache for 5 minutes
  });
  return res.json();
}

export default async function FeedPage() {
  const data = await getFeed();

  return (
    <div>
      <h1>Our Content</h1>
      {data.items.map(item => (
        <article key={item.id}>
          <h2>{item.title}</h2>
          {/* Render content here */}
        </article>
      ))}
    </div>
  );
}

Gatsby

Gatsby can fetch content at build time using gatsby-source-filesystem or directly in pages:

Using gatsby-node.js

// gatsby-node.js
exports.sourceNodes = async ({ actions, createNodeId, createContentDigest }) => {
  const { createNode } = actions;

  const res = await fetch('https://your-tenant.flarebuilder.com/api/feed?limit=100');
  const data = await res.json();

  data.items.forEach(item => {
    createNode({
      ...item,
      id: createNodeId(`FlareContent-${item.id}`),
      parent: null,
      children: [],
      internal: {
        type: 'FlareContent',
        contentDigest: createContentDigest(item)
      }
    });
  });
};

// src/pages/feed.js
import { graphql } from 'gatsby';

export const query = graphql`
  query {
    allFlareContent {
      nodes {
        id
        title
        tags
      }
    }
  }
`;

export default function FeedPage({ data }) {
  return (
    <div>
      {data.allFlareContent.nodes.map(item => (
        <article key={item.id}>
          <h2>{item.title}</h2>
        </article>
      ))}
    </div>
  );
}

Astro

Astro makes it easy to fetch content at build time:

---
// src/pages/feed.astro
const response = await fetch('https://your-tenant.flarebuilder.com/api/feed?limit=10');
const data = await response.json();
const items = data.items;
---

<html>
  <head>
    <title>Our Content</title>
  </head>
  <body>
    <h1>Our Content</h1>
    {items.map(item => (
      <article>
        <h2>{item.title}</h2>
        {item.tags && (
          <div class="tags">
            {item.tags.map(tag => (
              <span class="tag">{tag}</span>
            ))}
          </div>
        )}
      </article>
    ))}
  </body>
</html>

Hugo

Hugo can fetch external data using getJSON:

{{/* layouts/feed/list.html */}}
{{ $feed := getJSON "https://your-tenant.flarebuilder.com/api/feed?limit=10" }}

<h1>Our Content</h1>

{{ range $feed.items }}
  <article>
    <h2>{{ .title }}</h2>

    {{ if .tags }}
      <div class="tags">
        {{ range .tags }}
          <span class="tag">{{ . }}</span>
        {{ end }}
      </div>
    {{ end }}

    {{ if .sections }}
      {{ range $sectionId, $fields := .sections }}
        <div>
          {{ range $fieldId, $value := $fields }}
            {{ if eq $fieldId "image" }}
              <img src="{{ $value }}" alt="">
            {{ else if eq $fieldId "content_html" }}
              {{ $value | safeHTML }}
            {{ end }}
          {{ end }}
        </div>
      {{ end }}
    {{ end }}
  </article>
{{ end }}

Jekyll

Jekyll doesn't natively support API calls during build. Instead, use the FlareBuilder SDK at runtime or create a plugin:

Runtime with SDK (Recommended)

<!-- feed.html -->
---
layout: default
title: Our Content
---

<div id="flare-feed"></div>

<script src="https://flarebuilder.com/v1/flarebuilder.js"></script>
<script>
  const feed = new FlareBuilder.Feed({
    tenant: 'your-tenant',
    container: '#flare-feed',
    filters: {
      limit: 10,
      status: 'active'
    },
    render: {
      item: (item) => {
        let html = `<article>`;
        html += `<h2>${item.title}</h2>`;
        // Add your rendering logic
        html += `</article>`;
        return html;
      }
    }
  });
</script>

Build-time with Custom Plugin

Create a Jekyll plugin to fetch data at build time:

# _plugins/flarebuilder.rb
require 'net/http'
require 'json'

module Jekyll
  class FlareBuilderGenerator < Generator
    safe true
    priority :high

    def generate(site)
      url = 'https://your-tenant.flarebuilder.com/api/feed?limit=100'
      uri = URI(url)
      response = Net::HTTP.get(uri)
      data = JSON.parse(response)

      site.data['flarebuilder'] = data['items']
    end
  end
end

Then use the data in your templates:

{% for item in site.data.flarebuilder %}
  <article>
    <h2>{{ item.title }}</h2>
    {% if item.tags %}
      <div class="tags">
        {% for tag in item.tags %}
          <span class="tag">{{ tag }}</span>
        {% endfor %}
      </div>
    {% endif %}
  </article>
{% endfor %}
✓ Done!
You've integrated FlareBuilder with your static site generator.

Next Steps