Integrate a Hero Section
Sometimes you want to just one section of a page to be visually editable, such as for the hero section of a common page, like a collection page.
Model definition
A standard section model named collection-hero is all you need. Name this section based on what kind of page this section is on, such as if it's on a product collection page. Another example is if this section is on a different page type, such as a product page, you may want to use a more fitting name like product-hero.
By default, you don't need any fields. Instead, use targeting to determine if different visitors or pages should see a different hero.
Example code
// pages/collections/[collection].jsx
import { BuilderComponent, builder } from '@builder.io/react';
// Replace with your Public API Key.
builder.init(YOUR_API_KEY);
export async function getStaticProps({ params }) {
const urlPath = '/' + (params?.page?.join('/') || '');
const hero = await builder
.get('collection-hero', {
userAttributes: {
// Here, you can target different hero sections
// to different URL paths. Optionally, add other properties to target
urlPath
}
})
.toPromise();
return {
props: {
hero: hero || null,
},
};
}
export default function Page({ hero }) {
return (
<>
{/* Put your header here. */}
<YourHeader />
<BuilderComponent model="collection-hero" content={hero} />
{/* Put the rest of your page here. */}
<TheRestOfYourPage />
</>
);
}import {
BuilderContent,
Content,
fetchOneEntry,
isEditing,
isPreviewing,
} from '@builder.io/sdk-react/edge';
import { GetStaticPaths, GetStaticProps } from 'next';
import DefaultErrorPage from 'next/error';
import Head from 'next/head';
import { useRouter } from 'next/router';
// TO DO: Replace with your Public API Key
const YOUR_API_KEY = YOUR_PUBLIC_API_KEY;
// Define a function that fetches the Builder content for a given page
export const getStaticProps: GetStaticProps = async ({ params }) => {
const urlPath = '/' + (Array.isArray(params?.page) ? params.page.join('/') : params?.page || '');
// Fetch the Builder content for the given page using the 'collection-hero' model
const collectionHero = await fetchOneEntry({
apiKey: YOUR_API_KEY,
model: 'collection-hero',
userAttributes: { urlPath },
});
return {
// Return the Page content as props
props: { collectionHero },
revalidate: 5,
};
};
// Define a function that generates the
// static paths for all Pages in Builder
export const getStaticPaths: GetStaticPaths = async () => {
return {
paths: [],
fallback: 'blocking',
};
};
// Define the Page component
export default function Page(props: { collectionHero: BuilderContent | null }) {
const router = useRouter();
const canShowContent =
props.collectionHero || isPreviewing(router.asPath) || isEditing(router.asPath);
if (!canShowContent) {
return <DefaultErrorPage statusCode={404} />;
}
// If the page content is available, render
// the BuilderComponent with the page content
return (
<>
<YourHeader />
{/* Render the 'collection-hero' content if available */}
{props.collectionHero && <Content content={props.collectionHero} model="collection-hero" apiKey={YOUR_API_KEY} />}
{/* The rest of your page content */}
<TheRestOfYourPage />
</>
);
}// Example file structure, app/[...page]/page.tsx
// You could alternatively use src/app/[...page]/page.tsx
import { builder } from "@builder.io/sdk";
import Head from "next/head";
import { RenderBuilderContent } from "@/components/builder";
// Replace with your Public API Key
builder.init('YOUR_API_KEY');
interface PageProps {
params: {
page: string[];
};
}
export default async function Page(props: PageProps) {
const builderModelName = "collection-hero";
const collectionHeroContent = await builder
// Get the page content from Builder
.get(builderModelName, {
userAttributes: {
// Use the page path specified in the URL to fetch the content
urlPath: "/" + (props?.params?.page?.join("/") || ""),
},
// Set prerender to false to prevent infinite rendering loops
prerender: false,
})
.toPromise();
return (
<>
<Head>
<title>{collectionHeroContent?.data.title}</title>
</Head>
{/* Render the Builder page */}
<RenderBuilderContent
model={builderModelName}
content={collectionHeroContent} />
</>
);
}
Notice that RenderBuilderContent is a component you'd make, for example:
"use client";
import { ComponentProps } from "react";
import { BuilderComponent, useIsPreviewing } from "@builder.io/react";
import DefaultErrorPage from "next/error";
type BuilderPageProps = ComponentProps<typeof BuilderComponent>;
export function RenderBuilderContent(props: BuilderPageProps) {
const isPreviewing = useIsPreviewing();
if (props.content || isPreviewing) {
return <BuilderComponent {...props} />;
}
return null;
}// path of file: `src/app/[...slug]/page.tsx`
// You could alternatively use src/app/[...slug]/page.tsx
import { Content, fetchOneEntry, isEditing, isPreviewing, getBuilderSearchParams } from '@builder.io/sdk-react/edge';
import DefaultErrorPage from 'next/error';
import { useRouter } from 'next/router';
// TO DO: Replace with your Public API Key
const YOUR_API_KEY = YOUR_PUBLIC_API_KEY;
interface PageProps {
params: {
page: string[];
};
}
// Define the Page component
export default async function Page({ params }: PageProps) {
const router = useRouter();
const urlPath = '/' + (Array.isArray(params?.page) ? params.page.join('/') : params?.page || '');
// Fetch the builder content for the given page using the 'collection-hero' model
const collectionHero = await fetchOneEntry({
apiKey: YOUR_API_KEY,
model: 'collection-hero',
options: getBuilderSearchParams(props.searchParams),
userAttributes: { urlPath },
});
// Determine if content is available or if the page is being previewed or edited
const canShowContent = collectionHero || isPreviewing(router.asPath) || isEditing(router.asPath);
if (!canShowContent) {
return <DefaultErrorPage statusCode={404} />;
}
return (
<>
<YourHeader />
{/* Render the 'collection-hero' content if available */}
{collectionHero && (
<Content content={collectionHero} model="collection-hero" apiKey={YOUR_API_KEY} />
)}
<TheRestOfYourPage />
</>
);
}
Install the Builder React SDK:
npm install @builder.io/reactCreate a new React component; for example, CollectionPage.js, and set up Builder.io in your component:
// src/components/CollectionPage.js
import React, { useState, useEffect } from 'react';
import { BuilderComponent, builder } from '@builder.io/react';
// Replace with your Public API Key.
builder.init(YOUR_API_KEY);
const CollectionPage = ({ urlPath }) => {
const [hero, setHero] = useState(null);
useEffect(() => {
async function fetchData() {
const fetchedHero = await builder
.get('collection-hero', {
userAttributes: {
urlPath,
},
})
.toPromise();
setHero(fetchedHero);
}
fetchData();
}, [urlPath]);
return (
<>
{/* Put your header here. */}
<YourHeader />
{hero && <BuilderComponent model="collection-hero" content={hero} />}
{/* Put the rest of your page here. */}
<TheRestOfYourPage />
</>
);
};
export default CollectionPage;
// src/App.js
import React from 'react';
import CollectionPage from './components/CollectionPage';
function App() {
return (
<div className="App">
{/* Replace "/your-url-path" with the desired URL path. */}
<CollectionPage urlPath="/your-url-path" />
</div>
);
}
export default App;
Import the CollectionPage component and use it in your main React application:
// src/App.js
import React from 'react';
import CollectionPage from './components/CollectionPage';
function App() {
return (
<div className="App">
{/* Replace "/your-url-path" with the desired URL path. */}
<CollectionPage urlPath="/your-url-path" />
</div>
);
}
export default App;
Install the Builder React SDK:
npm install @builder.io/sdk-reactFetch the hero content:
import { Content, fetchOneEntry, getBuilderSearchParams } from '@builder.io/sdk-react';
import { useEffect, useState } from 'react';
// TODO: enter your Public API Key
const YOUR_API_KEY = 'YOUR_API_KEY';
function App() {
const [collectionHero, setCollectionHero] = useState(null);
useEffect(() => {
const urlPath = '/' + (window.location.pathname.split('/').slice(1).join('/') || '');
fetchOneEntry({
model: 'collection-hero',
apiKey: YOUR_API_KEY,
options: getBuilderSearchParams(new URL(location.href).searchParams),
userAttributes: { urlPath },
}).then(fetchedCollectionHero => setCollectionHero(fetchedCollectionHero));
}, []);
return (
<>
<YourHeader />
{/* Render the 'collection-hero' content if available */}
{collectionHero && <Content content={collectionHero} model="collection-hero" apiKey={YOUR_API_KEY} />}
<TheRestOfYourPage />
</>
);
}
export default App;Install the Builder React SDK:
npm install @builder.io/sdk-reactPaste the following code into a new file within the routes directory called $.tsx, making sure to replace YOUR_API_KEY with your Public API Key.
// $.tsx
import {
fetchOneEntry,
isEditing,
isPreviewing,
Content,
} from "@builder.io/sdk-react";
import type { LoaderFunction } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
export const loader: LoaderFunction = async ({ params, request }) => {
const url = new URL(request.url);
const apiKey = "YOUR_API_KEY"; // Replace with your API key
const content = await fetchOneEntry({
model: "collection-hero",
apiKey: apiKey,
options: url.searchParams,
userAttributes: {
urlPath: `/${params["*"]}`,
// add other targeting options
},
});
const isEditingOrPreviewing = isEditing() || isPreviewing();
if (!content && !isEditingOrPreviewing) {
// if section doesn't exist, return an empty object
return { content: null };
}
return { content };
};
// Define a page.
export default function Page() {
// Use the useLoaderData hook to get the collection-hero data from `loader` above.
const { content } = useLoaderData<typeof loader>();
// Render the collection-hero content from Builder.io
return (
<Content
model="collection-hero"
apiKey="YOUR_API_KEY" // Replace with your API key
content={content}
/>
);
}Replace YOUR_API_KEY with your Public API key.
Ensure that you have configured your routes so that URLs that match the pattern /collections/* are mapped to the collection route. You can do this in your remix.config.js file by adding the following code:
// remix.config.js
module.exports = {
// ... other configuration options
routes: [
{
// This matches URLs that start with "/collections/" and have
// additional segments after that.
// Example: "/collections/new-arrivals" or "/collections/mens-clothing".
// The ":collection" parameter will be available in the `params` object.
// Example: params.collection will be "new-arrivals" or "mens-clothing".
match: routes`/collections/:...page`,
loader: () => import('./routes/collections/[collection]'),
},
// ... other routes
],
};Want the latest and greatest of Remix with Builder? We recommend using Gen 2.
Install the Builder React SDK:
npm install @builder.io/reactCopy and paste the following code snippet into your file, for example src/routes/collection.js:
// $.tsx or, for example, src/routes/collection.js
import { BuilderComponent, builder } from "@builder.io/react";
import type { LoaderArgs } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
builder.init(YOUR_PUBLIC_API_KEY);
export const loader = async ({ params, request }: LoaderArgs) => {
const collectionHero = await builder
.get("collection-hero", {
userAttributes: {
urlPath: `/${params["*"]}`,
},
})
.toPromise();
const isPreviewing = new URL(request.url).searchParams.has("builder.preview");
if (!collectionHero && !isPreviewing) {
return null;
}
return { collectionHero };
};
export default function Page() {
const { collectionHero } = useLoaderData<typeof loader>();
return collectionHero ? (
<BuilderComponent model="collection-hero" content={collectionHero} />
) : null;
}
Paste the following code into a new file within the routes directory called $.tsx, making sure to replace YOUR_API_KEY with your Public API Key.
// $.tsx
import {
fetchOneEntry,
isEditing,
isPreviewing,
Content,
getBuilderSearchParams
} from "@builder.io/sdk-react";
import type { LoaderFunction } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
export const loader: LoaderFunction = async ({ params, request }) => {
const url = new URL(request.url);
const apiKey = "YOUR_API_KEY"; // Replace with your API key
const content = await fetchOneEntry({
model: "collection-hero",
apiKey: apiKey,
options: getBuilderSearchParams(event.url.searchParams),
userAttributes: {
urlPath: `/${params["*"]}`,
// add other targeting options
},
});
const isEditingOrPreviewing = isEditing() || isPreviewing();
if (!content && !isEditingOrPreviewing) {
// if section doesn't exist, return an empty object
return { content: null };
}
return { content };
};
// Define a page.
export default function Page() {
// Use the useLoaderData hook to get the collection-hero data from `loader` above.
const { content } = useLoaderData<typeof loader>();
// Render the collection-hero content from Builder.io
return (
<Content
model="collection-hero"
apiKey="YOUR_API_KEY" // Replace with your API key
content={content}
/>
);
}Replace YOUR_API_KEY with your Public API key.
Ensure that you have configured your routes so that URLs that match the pattern /collections/* are mapped to the collection route. You can do this in your remix.config.js file by adding the following code:
// remix.config.js
module.exports = {
// ... other configuration options
routes: [
{
// This matches URLs that start with "/collections/" and have
// additional segments after that.
// Example: "/collections/new-arrivals" or "/collections/mens-clothing".
// The ":collection" parameter will be available in the `params` object.
// Example: params.collection will be "new-arrivals" or "mens-clothing".
match: routes`/collections/:...page`,
loader: () => import('./routes/collections/[collection]'),
},
// ... other routes
],
};Want the latest and greatest of Hydrogen with Builder? We recommend using Gen 2.
Install the Builder React SDK:
npm install @builder.io/reactPaste the following code into a new file within the routes directory called $.tsx, making sure to replace YOUR_API_KEY with your Public API Key.
// $.tsx
import { BuilderComponent, builder } from "@builder.io/react";
import type { LoaderArgs } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
builder.init(YOUR_PUBLIC_API_KEY);
export const loader = async ({ params, request }: LoaderArgs) => {
const collectionHero = await builder
.get("collection-hero", {
userAttributes: {
urlPath: `/${params["*"]}`,
},
})
.toPromise();
const isPreviewing = new URL(request.url).searchParams.has("builder.preview");
if (!collectionHero && !isPreviewing) {
return null;
}
return { collectionHero };
};
export default function Page() {
const { collectionHero } = useLoaderData<typeof loader>();
return collectionHero ? (
<BuilderComponent model="collection-hero" content={collectionHero} />
) : null;
}
This example uses SvelteKit.
Install the SDK:
npm install @builder.io/sdk-svelteCopy the following into src/routes/collection/collection.js:
// src/routes/collections/[collection].js
import { fetchOneEntry, getBuilderSearchParams } from '@builder.io/sdk-svelte';
const BUILDER_PUBLIC_API_KEY = YOUR_API_KEY;
export async function load({ params }) {
const urlPath = '/' + (params?.page?.join('/') || '');
const content = await fetchOneEntry({
model: 'collection-hero',
apiKey: BUILDER_PUBLIC_API_KEY,
options: getBuilderSearchParams(event.url.searchParams),
userAttributes: {
urlPath,
},
});
return {
props: {
content,
},
};
}
Copy the following into src/routes/collections/[collection].svelte:
// src/routes/collections/[collection].svelte
<script>
import { load } from './collection.js';
import { Content } from '@builder.io/sdk-svelte';
export let content;
</script>
<main>
{/* Put your header here. */}
<YourHeader />
<Content model="collection-hero" {content} apiKey={BUILDER_PUBLIC_API_KEY} />
{/* Put the rest of your page here. */}
<TheRestOfYourPage />
</main>
<!-- Add your styles here -->
<style>
...
</style>
<script>
export { load };
</script>
Install the Builder Vue SDK:
npm install @builder.io/sdk-vueCreate a new Vue component; for example, CollectionPage.vue, and set up Builder.io in your component:
<!-- components/CollectionPage.vue -->
<template>
<div>
<!-- Put your header here. -->
<your-header></your-header>
<!-- Using the Content component to render the fetched content -->
<Content :model="'collection-hero'" :content="hero" :apiKey="YOUR_API_KEY" />
<!-- Put the rest of your page here. -->
<the-rest-of-your-page></the-rest-of-your-page>
</div>
</template>
<script>
import { Content, fetchOneEntry } from '@builder.io/sdk-vue';
import YourHeader from './YourHeader.vue';
import TheRestOfYourPage from './TheRestOfYourPage.vue';
export default {
components: {
YourHeader,
TheRestOfYourPage,
Content,
getBuilderSearchParams
},
data() {
return {
hero: null,
};
},
async mounted() {
const urlPath = this.$route.path;
try {
const hero = await fetchOneEntry({
model: 'collection-hero',
apiKey: 'YOUR_API_KEY', // Replace with your actual API key
options: getBuilderSearchParams(new URL(location.href).searchParams)
query: {
'data.urlPath': urlPath,
},
});
this.hero = hero;
} catch (error) {
console.error(`Oops: ${error}`);
}
},
</script>Import the CollectionPage component and use it in your main Vue application:
<!-- App.vue -->
<template>
<div id="app">
<CollectionPage />
</div>
</template>
<script>
import CollectionPage from './components/CollectionPage.vue';
export default {
name: 'App',
components: {
CollectionPage,
},
};
</script>
Install the Builder Vue SDK:
npm install @builder.io/sdk-vueCreate a new Vue component; for example, CollectionPage.vue, and set up Builder.io in your component:
<!-- components/CollectionPage.vue -->
<template>
<div>
<!-- Put your header here. -->
<your-header></your-header>
<Content :model="'collection-hero'" :content="hero" :apiKey="YOUR_API_KEY" />
<!-- Put the rest of your page here. -->
<the-rest-of-your-page></the-rest-of-your-page>
</div>
</template>
<script>
import { Content, fetchOneEntry } from '@builder.io/sdk-vue';
import YourHeader from '~/components/YourHeader.vue';
import TheRestOfYourPage from '~/components/TheRestOfYourPage.vue';
export default {
components: {
YourHeader,
TheRestOfYourPage,
Content,
},
async asyncData({ params }) {
// Ensure this matches how your routing is set up
const urlPath = params.path;
try {
const hero = await fetchOneEntry({
model: 'collection-hero',
apiKey: YOUR_API_KEY, // Replace with your API key
query: {
'data.urlPath': urlPath,
},
});
return { hero };
} catch (err) {
console.error(`Oops: ${err}`);
return { hero: null };
}
},
};
</script>Import the CollectionPage component and use it by adding it to a page:
<!-- pages/index.vue -->
<template>
<div>
<CollectionPage />
</div>
</template>
<script>
import CollectionPage from '~/components/CollectionPage.vue';
export default {
components: {
CollectionPage,
},
};
</script>Add the following to nuxt.config.js:
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
module: ['@builder.io/sdk-vue/nuxt'],
});If you are using an SSR framework other than Nuxt, you must import the CSS by adding the following to your entry point, before rendering Builder content:
<script>
import '@builder.io/sdk-vue/css';
</script>Install the necessary dependencies:
npm install @builder.io/qwik
npm install @builder.io/qwik-city
npm install @builder.io/sdk-qwikCreate a new Qwik component; for example, CollectionPage.tsx and set up Builder.io in your component:
import { component$ } from "@builder.io/qwik";
import { routeLoader$ } from "@builder.io/qwik-city";
import {
fetchOneEntry,
Content,
getBuilderSearchParams
} from "@builder.io/sdk-qwik";
export const BUILDER_PUBLIC_API_KEY = YOUR_API_KEY; // TO DO: Replace with your Public API Key
export const BUILDER_MODEL = "collection-hero";
export const useBuilderContent = routeLoader$(async ({ url, error }) => {
const builderContent = await fetchOneEntry({
model: BUILDER_MODEL,
apiKey: BUILDER_PUBLIC_API_KEY,
options: getBuilderSearchParams(url.searchParams),
});
return builderContent;
});
export default component$(() => {
const content = useBuilderContent();
return (
<Content
model={BUILDER_MODEL}
content={content.value}
apiKey={BUILDER_PUBLIC_API_KEY}
/>
);
});The following App.js code is an example of integrating a collection-hero model. Make sure to replace YOUR_API_KEY with your Public API Key:
// App.js
import React, { useEffect, useState } from 'react';
import { Text, View } from 'react-native';
import { Content, fetchOneEntry } from '@builder.io/sdk-react-native';
const BUILDER_API_KEY = YOUR_API_KEY;
const BuilderContent = () => {
const [content, setContent] = useState(null);
useEffect(() => {
const options = { /* your options here */ };
fetchOneEntry({
model: 'collection-hero',
apiKey: BUILDER_API_KEY,
options: options,
userAttributes: {
urlPath: '/',
},
})
.then(setContent)
.catch(err => console.error('Error fetching Builder Content: ', err));
}, []);
return (
<View style={{ padding: 20 }}>
<Text>Hello from your React Native codebase. Below is your Builder content:</Text>
{content ? (
<Content
apiKey={BUILDER_API_KEY}
model="collection-hero"
content={content}
/>
) : (
<Text>Not Found.</Text>
)}
</View>
);
};
export default BuilderContent;// collection-hero.component.ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { fetchOneEntry, type BuilderContent } from '@builder.io/sdk-angular';
import { Content } from '@builder.io/sdk-angular';
@Component({
selector: 'app-collection-hero',
standalone: true,
imports: [Content, CommonModule],
templateUrl: './collection-hero.component.html',
styleUrl: './collection-hero.component.css'
})
export class CollectionHeroComponent {
// Add your Public API Key, specify the page model, and initialize the content variable
apiKey = /* ADD YOUR PUBLIC API KEY HERE */;
model = 'collection-hero';
content: BuilderContent | null = null;
async ngOnInit() {
const urlPath = window.location.pathname || '';
// fetch the content for the current model based on the current URL
const content = await fetchOneEntry({
apiKey: this.apiKey,
model: this.model,
userAttributes: {
urlPath,
},
});
if (!content) {
return;
}
this.content = content;
}
}<!-- src/app/collection-hero.component.html -->
<ng-container *ngIf="content">
<builder-content
[model]="model"
[content]="content"
[apiKey]="apiKey">
</builder-content>
</ng-container>Fetch the data with a resolver:
// collection-hero.resolver.ts
import type { ActivatedRouteSnapshot, ResolveFn } from '@angular/router';
import { fetchOneEntry, getBuilderSearchParams } from '@builder.io/sdk-angular';
export const announcementBarResolver: ResolveFn<any> = (
route: ActivatedRouteSnapshot
) => {
const urlPath = `/${route.url.join('/')}`;
const searchParams = getBuilderSearchParams(route.queryParams);
return fetchOneEntry({
apiKey: /* PUT YOUR PUBLIC API KEY HERE */,
model: 'collection-hero',
userAttributes: {
urlPath,
},
options: searchParams,
});
};In collection-hero.component.ts, subscribe to the route's resolved data from the resolver, in order to render it in the template.
// src/app/collection-hero/collection-hero.component.ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ActivatedRoute } from '@angular/router';
import { Content, type BuilderContent } from '@builder.io/sdk-angular';
@Component({
selector: 'app-collection-hero',
standalone: true,
templateUrl: './collection-hero.component.html',
})
export class CollectionHeroComponent {
apiKey = '/* PUT YOUR PUBLIC API KEY HERE */';
model = 'collection-hero';
content: BuilderContent | null = null;
constructor(private activatedRoute: ActivatedRoute) {}
ngOnInit() {
this.activatedRoute.data.subscribe((data: any) => {
this.content = data.content;
});
}
}Update the template to show the collection hero.
<!-- app/collection-hero.component.html -->
<ng-container *ngIf="content; else notFound">
<builder-content
[model]="model"
[content]="content"
[apiKey]="apiKey"
></builder-content>
</ng-container>
<ng-template #notFound>
<div>404 - Content not found</div>
</ng-template>Install the Builder React SDK:
npm install @builder.io/reactCreate a new React component; for example, CollectionPage.js, and set up Builder.io in your component:
// src/components/CollectionPage.js
import React, { useState, useEffect } from 'react';
import { BuilderComponent, builder } from '@builder.io/react';
// Replace with your Public API Key.
builder.init(YOUR_API_KEY);
const CollectionPage = ({ urlPath }) => {
const [hero, setHero] = useState(null);
useEffect(() => {
async function fetchData() {
const fetchedHero = await builder
.get('collection-hero', {
userAttributes: {
urlPath,
},
})
.toPromise();
setHero(fetchedHero);
}
fetchData();
}, [urlPath]);
return (
<>
{/* Put your header here. */}
<YourHeader />
{hero && <BuilderComponent model="collection-hero" content={hero} />}
{/* Put the rest of your page here. */}
<TheRestOfYourPage />
</>
);
};
export default CollectionPage;
Import the CollectionPage component and use it in your main Gatsby application:
// src/pages/index.js
import React from 'react';
import { graphql } from 'gatsby';
import CollectionPage from '../components/CollectionPage';
const IndexPage = ({ location }) => {
return (
<div>
<CollectionPage urlPath={location.pathname} />
</div>
);
};
export default IndexPage;Make an HTTP GET request to the Builder.io REST API:
https://cdn.builder.io/api/v2/content/{model}?apiKey={your_api_key}&userAttributes.urlPath={url_path}Replace {model} with your model name; for example, collection-hero, {your_api_key} with your Public API key, and {url_path} with the URL path you want to target.
For example, using JavaScript Fetch API:
const apiKey = 'your_public_api_key';
const modelName = 'collection-hero';
const urlPath = '/your-url-path';
fetch(
`https://cdn.builder.io/api/v2/content/${modelName}?apiKey=${apiKey}&userAttributes.urlPath=${urlPath}`
)
.then((response) => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then((data) => {
console.log(data);
})
.catch((error) => {
console.error('There was a problem with the fetch operation:', error);
});This returns the JSON data for the specified model and URL path.
Use the returned JSON data in your application as required. You can use the data in any front-end framework or library to render the content.
The REST API does not include the rendering part, so you must handle that in your application. The returned JSON data contains the structure and content you can use to build your application's UI.
Import Builder and fetch the collection-hero, making sure to replace YOUR_PUBLIC_API_KEY with your Builder Public API Key.
// Import necessary libraries
import SwiftUI
import BuilderIO
struct ContentView: View {
@ObservedObject var content: BuilderContentWrapper = BuilderContentWrapper()
init() {
self.getContent()
}
// Define getContent as a method to fetch content from Builder.io
func getContent() {
Content.getContent(model: "collection-hero",
apiKey: YOUR_PUBLIC_API_KEY, // Replace with your Public API key
url: "", // No URL is needed for sections
locale: "",
preview: "") { content in
// The completion block to be executed once getContent is completed
// Ideally in the main thread because it likely updates UI components
DispatchQueue.main.async {
// Calls changeContent on self.content with the new content
self.content.changeContent(content)
}
}
}
var body: some View {
VStack {
if let contentValue = content.content {
// Use the content to render your section view
// TO DO: Replace with code to render your section
RenderContent(content: contentValue, apiKey: YOUR_PUBLIC_API_KEY)
} else {
// Display a loading message if the content is not yet available
Text("Loading...")
}
// Handle live previewing
if Content.isPreviewing() {
// Display a 'Reload' button during content previews for manual refresh
Button("Reload") {
self.getContent()
}
}
}
}
}
Install the Builder Angular SDK:
npm install @builder.io/angularIn your Angular application, open app.module.ts and import the BuilderModule:
// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { BuilderModule } from '@builder.io/angular';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, AppRoutingModule, BuilderModule.forRoot(YOUR_API_KEY)],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}Make sure to replace YOUR_API_KEY with your own Builder.io Public API key.
Create a new Angular component; for example, collection-hero with the Angular CLI.
ng g c collection-heroSet up Builder.io in your collection-hero component:
// src/app/collection-page/collection-page.component.ts
import { Component, OnInit } from '@angular/core';
import { Builder, builder } from '@builder.io/angular';
@Component({
selector: 'app-collection-hero',
templateUrl: './collection-hero.component.html',
styleUrls: ['./collection-hero.component.css'],
})
export class CollectionHeroComponent implements OnInit {
hero$ = builder.get('collection-hero', {
userAttributes: {
// Replace with the desired URL path.
urlPath: '/your-url-path',
},
});
constructor(private builder: Builder) {}
ngOnInit(): void {}
}
Update the component template to include the BuilderComponent:
<!-- src/app/collection-page/collection-page.component.html -->
<!-- Put your header here. -->
<your-header></your-header>
<builder-component modelName="collection-hero" [content]="hero$ | async"></builder-component>
<!-- Put the rest of your page here. -->
<the-rest-of-your-page></the-rest-of-your-page>
Import the CollectionPageComponent and use it in your main Angular application:
<!-- app.component.html -->
<app-collection-hero></app-collection-hero>