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
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.
You've integrated FlareBuilder with your static site generator.
Next Steps
- API Reference - Learn about filters, pagination, and more
- Webhooks - Trigger rebuilds when content changes
- SDK Reference - For runtime integration