To embark on the fascinating journey of paginating your content, you’ll need your Builder account. If you don’t have one yet, you can get started right here!
One impressive method involves a blend of Content API, Custom JS, Element Events, and Element Data Bindings. ( You can check this Content API Exlporer )
Before we dive into the details, if you haven’t already created an application and integrated it with BuilderIO, our Devtools make this process a breeze. Check out the QuickStart here and get ready for an exciting ride!
Assuming you’ve already created a page and set up a data model, let’s proceed.
In this example, I’m working with a Movies data model, featuring images and titles for each movie. We’ll paginate this content with 2 items per page.
Our weapon of choice for fetching content is the Content API, but you can also use your own API endpoint for data retrieval.
Now, take a moment to imagine a basic layout for displaying this content, complete with two navigation buttons for pagination:
Once you’ve crafted this page layout with elements, open the Edit Content JS + CSS tab from the data tab and paste the following code into the main function:
Make sure to replace your Builder API key in const MOVIES_CONTENT_API_URL
const MOVIES_CONTENT_API_URL = "https://cdn.builder.io/api/v3/content/movies?apiKey=<BUILDER_API_KEY>&limit=2&sort.name=1";
// Initialize state with offset and movieResults
state.offset = 0;
state.movieResults = [];
// Create a function to fetch movies based on the current offset
async function fetchMovies(offset) {
try {
const targetUrl = `${MOVIES_CONTENT_API_URL}&offset=${offset}`;
const response = await fetch(targetUrl);
if (response.ok) {
const data = await response.json();
// Check if there is no data for the given offset
if (data.results.length === 0) {
console.warn('No data found for offset:', offset);
return null;
}
return data;
} else {
console.error('Failed to fetch movies');
return null;
}
} catch (error) {
console.error('Error fetching movies:', error);
return null;
}
}
// Function to load movies based on the current offset and update state
function loadMovies() {
fetchMovies(state.offset)
.then((data) => {
if (data) {
state.movieResults = data;
}
})
.catch((error) => {
console.error('Error loading movies:', error);
});
}
// Create a function to handle next page
function nextPage() {
// Increment the offset by 2
state.offset += 2;
loadMovies();
}
// Create a function to handle previous page
function prevPage() {
// Ensure the offset doesn't go below 0
if (state.offset >= 2) {
// Decrement the offset by 2
state.offset -= 2;
loadMovies();
}
}
// Bind functions to the state
state.loadMovies = loadMovies;
state.nextPage = nextPage;
state.prevPage = prevPage;
// Initial load of movies
loadMovies();
This code fetches movie data from a specific API endpoint. It initializes state variables for the offset and movie results, defines functions to fetch and load movies based on the current offset, and creates functions for handling next and previous pages of movie results. These functions are then bound to the state and used for the initial load of movies.
Query Parameters used: limit, offset, sort. (Querying Cheatsheet)
Now that the data is in place, let’s bind it to a block for repetition. In my case, the results data is in state.movieResults.results
. Select the element you want to repeat, expand Element Data Binding
, and choose Repeat for each
. Your data options should appear as shown below:
Next, bind the image and text elements to the data from your API results. Watch the following Loom video for detailed steps.
Once you’ve completed these actions, publish the page, and voilà! You can now witness your pagination in action. Check it out here.
Exciting news! We’ll soon be adding a count to our Content API.
Another intriguing approach involves moving your logic to the server side and passing data and functions with the BuilderComponent. Here’s an example:
<BuilderComponent
model="page"
data={{
movies: movieList,
}}
context={{
nextPage: () => myService.nextPage(),
prevPage: () => myService.prevPage(),
}}
content={builderJson}
/>
Discover more about custom data and context here.
Alternatively, you can opt to create a custom pagination wrapper component.
We’d love to hear your thoughts! Share your ideas and experiences with implementing pagination within Builder. Let’s explore different use cases and address any pain points to enhance the overall experience.
Join the conversation on a similar topic in another post here.