How can I implement lazy loading of content using Astro.js and Hygraph pagination?
To implement lazy loading with Astro.js and Hygraph, start by querying a set of posts from the Hygraph API during the site build to render as static HTML. Then, add a React component (e.g., More.jsx) that uses the postsConnection query to fetch additional posts when a 'Load More' button is clicked. This approach leverages Astro's 'Islands Architecture' for selective hydration and uses the Relay cursor connection specification for efficient pagination. For a full walkthrough and code samples, see the original blog post. Note: For very large datasets, initial build time and client-side performance should be considered.
What is the benefit of using the postsConnection query in Hygraph for pagination?
The postsConnection query in Hygraph follows the Relay cursor connection specification, providing edges (posts), unique cursors, and a pageInfo object with start/end cursors and pagination booleans. This enables efficient fetching of content in pages, supports 'Load More' functionality, and avoids long build times or large payloads for static sites. Note: This method adds some query overhead compared to simple list queries but is necessary for scalable pagination. See Hygraph's pagination documentation for details.
How do I connect my Astro project to Hygraph for content fetching?
To connect Astro to Hygraph, clone the provided starter repository (see the GitHub start branch), create a .env file in the root, and set the HYGRAPH_ENDPOINT environment variable to your Hygraph project's API endpoint. This enables your Astro project to fetch content from Hygraph using GraphQL queries. Note: Ensure your API endpoint and permissions are correctly configured in Hygraph for content access.
What are the limitations of using static HTML for content-heavy pages in Astro.js?
When using static HTML generation in Astro.js for content-heavy pages (e.g., 100+ posts), build times and initial page load times can increase significantly. For large datasets, it's recommended to implement pagination and lazy loading (e.g., with Hygraph's postsConnection query and a 'Load More' button) to optimize performance. Note: Static generation is best suited for smaller datasets or when combined with client-side hydration for additional content.
Features & Capabilities
What APIs does Hygraph provide for content management and integration?
Hygraph offers several APIs: the GraphQL Content API for querying and manipulating content, the Management API for handling project structure, the Asset Upload API for uploading files, and the MCP Server API for secure AI assistant communication. Each API is optimized for high performance and low latency. For full details, see the API Reference documentation. Note: Some APIs require specific permissions or project configurations.
What integrations are available with Hygraph?
Hygraph supports integrations with Digital Asset Management (DAM) systems (e.g., Aprimo, AWS S3, Bynder, Cloudinary, Imgix, Mux, Scaleflex Filerobot), hosting and deployment platforms (Netlify, Vercel), Product Information Management (Akeneo), commerce solutions (BigCommerce), translation/localization (EasyTranslate), and others like Adminix and Plasmic. For the full list, visit the Hygraph Marketplace. Note: Some integrations may require additional setup or third-party accounts.
What performance optimizations does Hygraph offer for content delivery?
Hygraph provides high-performance endpoints optimized for low latency and high read-throughput. A read-only cache endpoint delivers 3-5x latency improvement, and the platform actively measures GraphQL API performance. For more, see the performance improvements blog post and the GraphQL Report 2024. Note: Actual performance may vary based on project configuration and query complexity.
Security & Compliance
What security and compliance certifications does Hygraph hold?
Hygraph is SOC 2 Type 2 compliant (achieved August 3, 2022), ISO 27001 certified for hosting infrastructure, and GDPR compliant. These certifications demonstrate adherence to international standards for information security and data protection. For more, see the Secure Features page. Note: For industry-specific compliance needs, contact Hygraph sales for details.
What security features are available in Hygraph?
Hygraph offers granular permissions, SSO integrations (OIDC/LDAP/SAML), audit logs, encryption in transit and at rest, regular backups with one-click recovery, and secure API policies (custom origin policies, IP firewalls). All endpoints have SSL certificates. For more, see the Secure Features page. Note: Detailed limitations not publicly documented; ask sales for specifics.
Use Cases & Benefits
Who can benefit from using Hygraph?
Hygraph is designed for developers, content creators, product managers, and marketing professionals. It is suitable for enterprises and high-growth companies in SaaS, eCommerce, media, healthcare, automotive, and more. Its flexibility and scalability support a wide range of use cases, from global content delivery to modular digital experiences. Note: Teams with highly specialized compliance or legacy system needs should confirm fit with Hygraph sales.
What business impact can customers expect from using Hygraph?
Customers have reported faster time-to-market (e.g., Komax achieved 3x faster launches), improved customer engagement (Samsung saw a 15% increase), and cost reduction (AutoWeb increased website monetization by 20%). Hygraph's content federation and API-first architecture support consistent, scalable digital experiences. See case studies for more. Note: Results may vary based on implementation and project scope.
What problems does Hygraph solve for content teams and developers?
Hygraph addresses developer dependency, legacy tech stack modernization, content inconsistency, workflow inefficiencies, high operational costs, slow speed-to-market, schema evolution complexity, integration challenges, performance bottlenecks, and localization/asset management issues. Its GraphQL-native architecture and content federation are designed to streamline modern content management. Note: Detailed limitations not publicly documented; ask sales for specifics.
Customer Success & Social Proof
Can you share specific case studies or customer success stories with Hygraph?
Yes. Notable examples include Samsung (15% improved engagement), Komax (3x faster time-to-market), AutoWeb (20% increase in monetization), BioCentury (accelerated publishing), Voi (scaled multilingual content across 12 countries), and HolidayCheck (reduced developer bottlenecks). See the case studies page for details and more customer stories. Note: Outcomes depend on project specifics and implementation.
What feedback have customers given about Hygraph's ease of use?
Customers have praised Hygraph for its intuitive interface, quick adaptability, and accessibility for non-technical users. For example, Sigurður G. (CTO) noted the UI is intuitive, Anastasija S. (Product Content Coordinator) highlighted instant front-end updates, and Charissa K. (Senior CMS Specialist) emphasized the clear setup and localization features. Note: Some advanced features may require developer involvement.
Support & Implementation
How long does it take to implement Hygraph and how easy is it to start?
Implementation time varies by project. For example, Top Villas launched in 2 months, Voi migrated from WordPress in 1-2 months, and Si Vale met aggressive deadlines in the initial phase. Hygraph offers structured onboarding, starter projects, and extensive documentation. Users can sign up for a free account, access guides, and join the Slack community. Note: Complex migrations or integrations may require additional time and technical resources.
What technical documentation is available for Hygraph users?
Hygraph provides comprehensive technical documentation, including API references, schema guides, getting started tutorials, integration guides (e.g., Mux, Akeneo, Auth0), and AI feature documentation. Classic docs are available for legacy users. See the Hygraph Documentation for all resources. Note: Some advanced topics may require developer expertise.
Industries & Use Case Coverage
What industries are represented in Hygraph's case studies?
Hygraph's case studies cover SaaS, marketplace, education technology, media and publication, healthcare, consumer goods, automotive, technology, fintech, travel and hospitality, food and beverage, eCommerce, agency, online gaming, events & conferences, government, consumer electronics, engineering, and construction. See the case studies page for examples. Note: Industry-specific requirements should be discussed with Hygraph sales.
Implementing lazy load content with Astro.js and Hygraph pagination
In the demo, we’ll load a set of posts as static HTML created during the site build and then implement a load more button in React to query Hygraph for more content and load that onto the page.
Last updated by Bryan
on Jan 21, 2026
Originally written by Bryan
With the ever-tumultuous nature of social media, sometimes owning your own content and publishing on your own platform is better. In this article, we’re going to take a look at implementing a standard pattern of the social media world: the load more button.
In the demo, we’ll load a set of posts as static HTML created during the site build and then implement a load more button in React to query Hygraph for more content and load that onto the page.
Astro is a relatively new player in the frontend framework world. Their underlying philosophy is that while we may want to author our websites in JavaScript, we don’t need to ship all that JavaScript to the browser just to have a bit of interactivity.
Astro is an HTML-first platform that statically builds the HTML during a deployment process and then selectively rehydrates parts of the user interface based on client-side needs. This is often referred to as “Islands Architecture” and differs from traditional meta frameworks in that Astro doesn’t want to take over the entire page for simple hydration of one area.
Astro also isn’t beholden to any singular framework like React. While we’ll be using React in this example, it could also be built from Vue, Svelte, or JavaScript.
To get things started, I’ve put together a relatively simple Astro site that is querying Hygraph for posts in a Post schema. If you’d like to follow along, you can use Hygraph’s Blog starter schema or create a blank project and add a Post schema with two fields: slug and content (rich text). Since this is a “microblog,” we don’t need more than that. If you’re using the blog starter, you’ll have that by default (along with other fields we won’t use in this project).
You can get the starting point project from this GitHub repository on the “start” branch. This gives you all the functionality you need to connect your Hygraph project to Astro and see all the posts on the homepage.
Clone the repository and create a .env file in the root and add the HYGRAPH_ENDPOINT environment variable with a value of the Hygraph project’s API endpoint.
Now, we’re ready to get rolling.
#Getting pages of content instead of simply the content
To begin, the project is currently pulling a set number of posts from the Hygraph API to the homepage in the src/index.astro file. It’s using a JavaScript fetch in the frontmatter to query and get the first 10 posts from the API and return back their ID, createdAt date, HTML content, and slug.
It then gets the posts off the response and sends that to the Astro template to render each post with that information.
---
import Main from "../layouts/Main.astro";
import Post from "../components/Post.astro";
const pageSize = 10;
const response = await fetch(
"THE-LINK-TO-YOUR-ENDPOINT",
{
method:"POST",
headers:{
"Content-Type":"application/json",
Accept:"application/json",
},
body: JSON.stringify({
query: `query MyQuery($size: Int) {
posts(first: $size, orderBy: createdAt_DESC) {
id
createdAt
slug
content {
html
}
}
}
`,
variables:{size: pageSize}
}),
}
);
const data = await response.json();
const {posts} = data.data;
---
<Main title="My Microblog">
<div>
{posts.map((post) => {
return <Post post={post} />
})}
</div>
</Main>
This is fine when you have a small number of posts, but if you want 100 posts on the homepage, the build time and load time are going to get longer and longer. Not great for developer experience or user experience. While using a posts() query is great for getting started, we’ll want to switch to a method more suited for larger projects.
For each model you create, Hygraph creates a standard query and a connections query for it. This specialized connection query gives us all the information we need to properly paginate and request content at various points in the model’s content. Hygraph follows the Relay cursor connection specification and does all the API work for you to make sure it’s ready for use in the postsConnections query.
This new query let’s us query pages of data instead of the data itself. While it adds a bit of overhead, it makes up for that with all the data we need to properly work:
Posts are edges in our query
Each post has a unique cursor point and all the original post data
Each query will also return a unique pageInfo object which gives us a start and end cursor, booleans for next and previous pages, and the total page size
The start and end cursors can be used to get the next or previous set of posts
Let’s restructure the homepage query to get a page of content instead of just a number of posts. To do this, we need to change from using the posts() query to postsConnections() and restructure the returned data. We still use the pageSize variable to define how many items each page should hold and then pass that data as pages instead of posts to the Astro template to loop over.
Now, we have 3 posts pulling into the homepage. How do we get the rest? We need a new component to create a “Load More” button and provide a landing zone for the new posts in our interactive island.
In the src/components directory, create a new file named More.jsx. We’ll start by just adding the load more button when the component is added to the homepage.
Since this little island of interactivity is going to be a React component, we start by importing React. Astro is already configured to support React in the starter code, but if you were starting from scratch, you’d need to configure Astro to be ready for React components.
Adding the button
First, we’ll create our component with two properties — currentCursor and size. These props will get passed to this component when it’s added to the index file.
From there, we need to set up a few pieces of state that will be useful throughout this process: a blank posts array, the cursor set to the currentCursor prop, a boolean for hasNext set to true and a loading boolean set to false.
We can then return a little markup to display a button with a click handler set to a getMore async function. This function is where much of the code will live in the next step. As a bit of added flair, let’s also make sure to have a small Loading indicator for when those posts are loaded. Check to see if loading is true and display the section if it is.
{hasNext && <button className="bg-white mb-4 p-4 rounded-md" onClick={getMore}>Get More </button>}
</>
);
}
export default More
Now that this component is created, we can add it to the page. In the src/index.astro file, import the component at the top and add the component after the loop through the posts. Since there may not be more posts to fetch, we want to make sure to only load the More component if the hasNextPage metadata is set to True.
When initializing the component, pass it the size and currentCursor props, but then we need to decide when we want to make this button ready. Astro provides a few directives for when to load our islands into the DOM. In this case, since the button will be near the bottom of the page and is not important for the user in how they interact with the first couple blog posts, I’ve set it to client:visible which will load this using the browser Intersection Observer API to know when the user scrolls the component into view. This will save on load time and keep page performance at a premium.
Now we should have a “Get More” button at the bottom of the page. The button doesn’t do anything yet. Let’s fix that.
Fetching more posts
As mentioned before, we need to handle what happens when a user clicks “Get More” so that new posts are fetched and added to the end of the list.
This query needs to be slightly different than the query from the initial Astro build for the index page. In this case, we need to also set the after property to the end item cursor we passed to our component. This is where the query will start and get a number of posts equal to the size value we also passed to the component. In other words, this gets the next 3 posts after the 3 we fetched for the index page.
We can use this new query in the getMore function.
To start the function, we set the loading state to true to display the loading information. Then we can fire off a new fetch request to Hygraph with the query we just wrote. From there, we can destructure the postsArray off the query and get the new pageInfo object. The pageInfo object has the same type of information as the homepage had. This will let us set a new endCursor and hasNext state for the new position.
Alongside these variables, we need to also set a state on the empty array of the posts variable. Even though the first state was an empty array, we want to set the state equal to the current state of posts — spread into the array — and the new set of posts in the postsArray variable. This ensures as we click the Get More button more, we keep the posts we’ve already fetched and just append new ones to the state.
Once the posts state has been updated, we can set the loading state back to false to remove the loading component. With that, we can now map over the posts array to display the content of the posts with the React PostContent component.
{hasNext && <button className="bg-white mb-4 p-4 rounded-md" onClick={getMore}>Get More </button>}
</>
);
}
export default More
We can now load all the posts one click at a time. When we reach a point where there are no more pages, the hasNext state will switch to false and the button will no longer be available for clicking.
Blog Author
Bryan Robinson
Head of Developer Relations
Bryan is Hygraph's Head of Developer Relations. He has a strong passion for developer education and experience as well as decoupled architectures, frontend development, and clean design.
Share with others
Sign up for our newsletter!
Be the first to know about releases and industry news and insights.
Implementing lazy load content with Astro.js and Hygraph pagination
In the demo, we’ll load a set of posts as static HTML created during the site build and then implement a load more button in React to query Hygraph for more content and load that onto the page.
Last updated by Bryan
on Jan 21, 2026
Originally written by Bryan
With the ever-tumultuous nature of social media, sometimes owning your own content and publishing on your own platform is better. In this article, we’re going to take a look at implementing a standard pattern of the social media world: the load more button.
In the demo, we’ll load a set of posts as static HTML created during the site build and then implement a load more button in React to query Hygraph for more content and load that onto the page.
Astro is a relatively new player in the frontend framework world. Their underlying philosophy is that while we may want to author our websites in JavaScript, we don’t need to ship all that JavaScript to the browser just to have a bit of interactivity.
Astro is an HTML-first platform that statically builds the HTML during a deployment process and then selectively rehydrates parts of the user interface based on client-side needs. This is often referred to as “Islands Architecture” and differs from traditional meta frameworks in that Astro doesn’t want to take over the entire page for simple hydration of one area.
Astro also isn’t beholden to any singular framework like React. While we’ll be using React in this example, it could also be built from Vue, Svelte, or JavaScript.
To get things started, I’ve put together a relatively simple Astro site that is querying Hygraph for posts in a Post schema. If you’d like to follow along, you can use Hygraph’s Blog starter schema or create a blank project and add a Post schema with two fields: slug and content (rich text). Since this is a “microblog,” we don’t need more than that. If you’re using the blog starter, you’ll have that by default (along with other fields we won’t use in this project).
You can get the starting point project from this GitHub repository on the “start” branch. This gives you all the functionality you need to connect your Hygraph project to Astro and see all the posts on the homepage.
Clone the repository and create a .env file in the root and add the HYGRAPH_ENDPOINT environment variable with a value of the Hygraph project’s API endpoint.
Now, we’re ready to get rolling.
#Getting pages of content instead of simply the content
To begin, the project is currently pulling a set number of posts from the Hygraph API to the homepage in the src/index.astro file. It’s using a JavaScript fetch in the frontmatter to query and get the first 10 posts from the API and return back their ID, createdAt date, HTML content, and slug.
It then gets the posts off the response and sends that to the Astro template to render each post with that information.
---
import Main from "../layouts/Main.astro";
import Post from "../components/Post.astro";
const pageSize = 10;
const response = await fetch(
"THE-LINK-TO-YOUR-ENDPOINT",
{
method:"POST",
headers:{
"Content-Type":"application/json",
Accept:"application/json",
},
body: JSON.stringify({
query: `query MyQuery($size: Int) {
posts(first: $size, orderBy: createdAt_DESC) {
id
createdAt
slug
content {
html
}
}
}
`,
variables:{size: pageSize}
}),
}
);
const data = await response.json();
const {posts} = data.data;
---
<Main title="My Microblog">
<div>
{posts.map((post) => {
return <Post post={post} />
})}
</div>
</Main>
This is fine when you have a small number of posts, but if you want 100 posts on the homepage, the build time and load time are going to get longer and longer. Not great for developer experience or user experience. While using a posts() query is great for getting started, we’ll want to switch to a method more suited for larger projects.
For each model you create, Hygraph creates a standard query and a connections query for it. This specialized connection query gives us all the information we need to properly paginate and request content at various points in the model’s content. Hygraph follows the Relay cursor connection specification and does all the API work for you to make sure it’s ready for use in the postsConnections query.
This new query let’s us query pages of data instead of the data itself. While it adds a bit of overhead, it makes up for that with all the data we need to properly work:
Posts are edges in our query
Each post has a unique cursor point and all the original post data
Each query will also return a unique pageInfo object which gives us a start and end cursor, booleans for next and previous pages, and the total page size
The start and end cursors can be used to get the next or previous set of posts
Let’s restructure the homepage query to get a page of content instead of just a number of posts. To do this, we need to change from using the posts() query to postsConnections() and restructure the returned data. We still use the pageSize variable to define how many items each page should hold and then pass that data as pages instead of posts to the Astro template to loop over.
Now, we have 3 posts pulling into the homepage. How do we get the rest? We need a new component to create a “Load More” button and provide a landing zone for the new posts in our interactive island.
In the src/components directory, create a new file named More.jsx. We’ll start by just adding the load more button when the component is added to the homepage.
Since this little island of interactivity is going to be a React component, we start by importing React. Astro is already configured to support React in the starter code, but if you were starting from scratch, you’d need to configure Astro to be ready for React components.
Adding the button
First, we’ll create our component with two properties — currentCursor and size. These props will get passed to this component when it’s added to the index file.
From there, we need to set up a few pieces of state that will be useful throughout this process: a blank posts array, the cursor set to the currentCursor prop, a boolean for hasNext set to true and a loading boolean set to false.
We can then return a little markup to display a button with a click handler set to a getMore async function. This function is where much of the code will live in the next step. As a bit of added flair, let’s also make sure to have a small Loading indicator for when those posts are loaded. Check to see if loading is true and display the section if it is.
{hasNext && <button className="bg-white mb-4 p-4 rounded-md" onClick={getMore}>Get More </button>}
</>
);
}
export default More
Now that this component is created, we can add it to the page. In the src/index.astro file, import the component at the top and add the component after the loop through the posts. Since there may not be more posts to fetch, we want to make sure to only load the More component if the hasNextPage metadata is set to True.
When initializing the component, pass it the size and currentCursor props, but then we need to decide when we want to make this button ready. Astro provides a few directives for when to load our islands into the DOM. In this case, since the button will be near the bottom of the page and is not important for the user in how they interact with the first couple blog posts, I’ve set it to client:visible which will load this using the browser Intersection Observer API to know when the user scrolls the component into view. This will save on load time and keep page performance at a premium.
Now we should have a “Get More” button at the bottom of the page. The button doesn’t do anything yet. Let’s fix that.
Fetching more posts
As mentioned before, we need to handle what happens when a user clicks “Get More” so that new posts are fetched and added to the end of the list.
This query needs to be slightly different than the query from the initial Astro build for the index page. In this case, we need to also set the after property to the end item cursor we passed to our component. This is where the query will start and get a number of posts equal to the size value we also passed to the component. In other words, this gets the next 3 posts after the 3 we fetched for the index page.
We can use this new query in the getMore function.
To start the function, we set the loading state to true to display the loading information. Then we can fire off a new fetch request to Hygraph with the query we just wrote. From there, we can destructure the postsArray off the query and get the new pageInfo object. The pageInfo object has the same type of information as the homepage had. This will let us set a new endCursor and hasNext state for the new position.
Alongside these variables, we need to also set a state on the empty array of the posts variable. Even though the first state was an empty array, we want to set the state equal to the current state of posts — spread into the array — and the new set of posts in the postsArray variable. This ensures as we click the Get More button more, we keep the posts we’ve already fetched and just append new ones to the state.
Once the posts state has been updated, we can set the loading state back to false to remove the loading component. With that, we can now map over the posts array to display the content of the posts with the React PostContent component.
{hasNext && <button className="bg-white mb-4 p-4 rounded-md" onClick={getMore}>Get More </button>}
</>
);
}
export default More
We can now load all the posts one click at a time. When we reach a point where there are no more pages, the hasNext state will switch to false and the button will no longer be available for clicking.
Blog Author
Bryan Robinson
Head of Developer Relations
Bryan is Hygraph's Head of Developer Relations. He has a strong passion for developer education and experience as well as decoupled architectures, frontend development, and clean design.
Share with others
Sign up for our newsletter!
Be the first to know about releases and industry news and insights.