# Creating the Hero Gallery Page

### About this export

| Field | Value |
| --- | --- |
| **content_type** | lesson |
| **platform** | contentstack-academy |
| **source_url** | https://www.contentstack.com/academy/courses/contentstack-for-developers/creating-the-hero-gallery-page |
| **course_slug** | contentstack-for-developers |
| **lesson_slug** | creating-the-hero-gallery-page |
| **markdown_file_url** | /academy/md/courses/contentstack-for-developers/creating-the-hero-gallery-page.md |
| **generated_at** | 2026-05-04T05:36:51.310Z |

> Part of **[Contentstack for Developers](https://www.contentstack.com/academy/courses/contentstack-for-developers)** on Contentstack Academy. **Academy MD v3** — structured for retrieval; no quiz or assessment keys.

<!-- ai_metadata: {"lesson_id":"17","type":"text","duration_minutes":1,"topics":["Creating","the","Hero","Gallery","Page"]} -->

#### Lesson text

## The Composable Hero Landing Page

Welcome to this tutorial on creating a superhero gallery page using reference fields in NextJS! In this module, we'll walk you through the steps of creating a new content type called "Superhero Gallery Page" and adding heroes to it manually. 

We'll start by showing you how to utilize reference fields to display hero content on the landing page with their images and names. This technique is commonly used in product promotions and article index pages, so it's a valuable skill to learn. 

Next, we'll guide you through the process of creating a new NextJS component and query to retrieve the Landing Page Entry and Reference field Hero Entries. Our NextJS component will loop through all the heroes in the reference field and display their titles, images, and links to their respective detail pages.

Finally, we'll demonstrate how to create a new Landing Page Entry and publish it to the Development environment to see the results of our work.

By the end of this tutorial, you'll have gained valuable knowledge on how to utilize reference fields in NextJS to create reusable content and enhance the user experience on your website. Let's get started!

![CSforDev\_L17\_ComposableHeroes.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt36760c2226f23188/67dc74d1443bd6f8bef1c126/CSforDev_L17_ComposableHeroes.png)

## **Hero Gallery Page Content Type**

![CSforDev\_L17-HeroGalleryPageContentType.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltca3a395e8b43a268/67dc74d25e486ddf7571ab5f/CSforDev_L17-HeroGalleryPageContentType.png)

#### Open the Superhero Gallery Page and examine the properties of each field

![CSforDev\_L17-SuperHeroGalleryPage.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt5d634d5af8ed1ef2/67dc74d120a3dc7d26f81da5/CSforDev_L17-SuperHeroGalleryPage.png)

**Review the following fields below:**

*   Title - Default Title field
    
*   URL - /gallery/:title
    
*   Heading - Text field
    
*   Description - Multi-line text
    
*   Characters - Reference field to the Character Content Type
    

## Part 2: Writing the code to display the list of heroes

**Let's list all the heroes in the reference field on the Gallery page.  Users can manually create a list of heroes and our code will loop over all the heroes in the reference field and render the name, image, and link.**   

### Rendering a list of Characters from a Reference Field

  
**1.  Create a NextJS Component for the Gallery page** and loop through all the heroes in the reference field, rendering the title, image and a link to the detail page.  This involves 2 steps, first writing the query function and then rendering the results.

  
**2.  Querying Contentstack for the Characters in the Reference Field**  
[In the /helpers/index.js file](https://github.com/contentstack/contentstack-academy-playground/blob/main/helper/index.js), review the function to get a list of heroes from the reference field

  
**3.**  [Review the code for the /composable-heroes/index.tsx file](https://github.com/contentstack/contentstack-academy-playground/blob/main/pages/composable-heroes/index.tsx)**.**  

  
**4.  Review the Composable Heroes Gallery Entry**

![CSforDev\_L17-ReviewComposableHeroesGalleryEntry.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blta1719b3c553d3aa7/67dc74d28fee9af26547d6d2/CSforDev_L17-ReviewComposableHeroesGalleryEntry.png)  

**5.  From the NextJS application, open the Composable Heroes Gallery Page**

![CSforDev\_L17-NextJSappOpenComposableHeroes.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt987109e80668c33d/67dc74d2c566ee77065df700/CSforDev_L17-NextJSappOpenComposableHeroes.png)

  

**2\. Introduction to using the Query functions of the Content Delivery API**

Contentstack provides certain queries that you can use to fetch filtered results. You can use queries for Entries and Assets API requests.  **Please review the** [Content Delivery Query API documentation](https://www.contentstack.com/docs/developers/apis/content-delivery-api/#queries) **and examine the RegEx, Limit and Only functions.**

**For the first part of the exercise, we can use a simple query to find all the entries with the Content Type of Character.**  

### Postman

**1.  Open Postman and select the Entries/Get Entries call**  
Update the parameters / variables so that:

*   content\_type\_uid = character
    
*   environment = development  
    

![CSforDev\_L17-Postman1.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltfc54a08558f3257d/67dc74d20c6f5573391fc550/CSforDev_L17-Postman1.png)

You should now have a list of the characters published to the development environment.  In the next section, we will use the JavaScript SDK to get the same list and pass it to the NextJS App to render.

  

**3\. Query using Javascript SDK**

In our web application we will mostly use the [Javascript Content Delivery SDK](https://www.contentstack.com/docs/developers/sdks/content-delivery-sdk/javascript-browser/reference/).  **Please have a look at the** [documentation for the query methods](https://www.contentstack.com/docs/developers/sdks/content-delivery-sdk/javascript-browser/reference/#query)**.**

Other SDKs can be found on the [SDKs documentation page](https://www.contentstack.com/docs/developers/sdks/)

import Contentstack from 'contentstack';  
const Stack = Contentstack.Stack({"api\_key": "api\_key", "delivery\_token": "delivery\_token", "environment": "environment"});  
const result = await Stack.ContentType('character').Query().toJSON().find();

[More information about this is found in the Javascript SDK Docs](https://www.contentstack.com/docs/developers/sdks/content-delivery-sdk/javascript-browser/reference/#stack-query)

## Composable Hero Landing Page

The Composable Hero Landing Page uses [Modular Blocks](https://www.contentstack.com/docs/developers/create-content-types/modular-blocks/) to provide a flexible structure for authors to create content and add as many content blocks to the page as they wish and also to re-order the blocks.  

![CSforDev\_L17-ComposableLandingPage.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt20cf9dbe38b2ce7a/67dc74d2dd73e3150dbf2aca/CSforDev_L17-ComposableLandingPage.png)

  

## Open the Superhero Landing Page Entry and review the content

![CSforDev\_L17-OpenSyperheroLandingPage.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltbd496f6c2aa7c3fb/67dc74d1632b938d87d497f4/CSforDev_L17-OpenSyperheroLandingPage.png)

##   

## Open the Content Type Definition and examine how the Modular Blocks field is used. 

Notice the fields are greyed out - that is because the Modular Block fields are defined using Global Fields.  This is a best practice.

![CSforDev\_L17-OpenContentTypeDefinition.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltcb805c91070decc1/67dc74d18fee9a015647d6ce/CSforDev_L17-OpenContentTypeDefinition.png)

## Global Field Definitions

![CSforDev\_L17-GlobalFieldDefinitions.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt133ae7c39bec81dd/67dc74d1782bfb40816f4d07/CSforDev_L17-GlobalFieldDefinitions.png)

##   

## Examine the Code used for the Hero Landing Page

The [**code for the Gallery Entry (Page)**](https://github.com/contentstack/contentstack-academy-playground/blob/main/pages/gallery.tsx) loops through all the Modular Blocks on the page and renders each one with its' own NextJS Component.  
![CSforDev\_L17-CodeForGalleryEntry.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt32ad6ea1b6068a60/67dc74d16f68587885fd9e35/CSforDev_L17-CodeForGalleryEntry.png)

## Each block is rendered with its own NextJS Component

*   [Gallery Block](https://github.com/contentstack/contentstack-academy-playground/blob/main/components/gallery.tsx)[  
    ](https://github.com/contentstack/contentstack-academy-playground/blob/main/components/gallery.tsx)![CSforDev\_L17-BlockRenderwithNextJScomp.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt6997b78ab65f5110/67dc74d1bbf93ef9c3586444/CSforDev_L17-BlockRenderwithNextJScomp.png)
    
      
      
    
*   [Hero Banner Block](https://github.com/contentstack/contentstack-academy-playground/blob/main/components/hero-banner.tsx)
    
    ![CSforDev\_L17-HeroBannerBlock.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt57deb882be0262c1/67dc74d1db243fda9112b9df/CSforDev_L17-HeroBannerBlock.png)[  
    ](https://github.com/contentstack/contentstack-academy-playground/blob/main/components/hero-banner.tsx)
    

By adopting this approach, we can isolate the HTML/Code for each block within a single NextJS Component. This simplifies maintenance and enables easy extension of the page in the future by adding a Modular Block and NextJS Component for additional content block types. 

With this method, you can modify the individual content blocks without having to make changes to the entire page structure. This approach makes the codebase more organized and easier to manage, especially when dealing with complex web applications. 

By leveraging this technique, you can increase the scalability and modularity of your website, allowing you to add new features and functionalities with ease.

#### Key takeaways

- Connect **Creating the Hero Gallery Page** back to your stack configuration before moving to the next module.
- Capture one concrete artifact (screenshot, Postman call, or code snippet) that proves the step works in your environment.
- Re-read the delivery versus management boundary for anything you changed in the entry model.

## Supplement for indexing

### Content summary

Creating the Hero Gallery Page. The Composable Hero Landing Page Welcome to this tutorial on creating a superhero gallery page using reference fields in NextJS! In this module, we'll walk you through the steps of creating a new content type called "Superhero Gallery Page" and adding heroes to it manually. We'll start by showing you how to utilize reference fields to display hero content on the landing page with their images and names. This technique is commonly used in product promotions and article index pages, so it's a valuable skill to learn. Next, we'll guide you through the process of creating a new NextJS component and query to retrieve the Landing Page Entry and Reference field Hero Entries. Our NextJS component wi

### Retrieval tags

- Creating
- the
- Hero
- Gallery
- Page
- contentstack-for-developers
- lesson 17
- Creating the Hero Gallery Page
- contentstack-for-developers lesson

### Indexing notes

Index this lesson as a primary chunk tagged with lesson_id "17" and topics: [Creating, the, Hero, Gallery, Page].
Parent course slug: contentstack-for-developers. Use asset_references URLs as thumbnail hints in search results when present.
Never surface LMS quiz content or assessment answers from this file.

### Asset references

| Label | URL |
| --- | --- |
| CSforDev\_L17\_ComposableHeroes.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt36760c2226f23188/67dc74d1443bd6f8bef1c126/CSforDev_L17_ComposableHeroes.png` |
| CSforDev\_L17-HeroGalleryPageContentType.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltca3a395e8b43a268/67dc74d25e486ddf7571ab5f/CSforDev_L17-HeroGalleryPageContentType.png` |
| CSforDev\_L17-SuperHeroGalleryPage.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt5d634d5af8ed1ef2/67dc74d120a3dc7d26f81da5/CSforDev_L17-SuperHeroGalleryPage.png` |
| CSforDev\_L17-ReviewComposableHeroesGalleryEntry.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blta1719b3c553d3aa7/67dc74d28fee9af26547d6d2/CSforDev_L17-ReviewComposableHeroesGalleryEntry.png` |
| CSforDev\_L17-NextJSappOpenComposableHeroes.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt987109e80668c33d/67dc74d2c566ee77065df700/CSforDev_L17-NextJSappOpenComposableHeroes.png` |
| CSforDev\_L17-Postman1.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltfc54a08558f3257d/67dc74d20c6f5573391fc550/CSforDev_L17-Postman1.png` |
| CSforDev\_L17-ComposableLandingPage.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt20cf9dbe38b2ce7a/67dc74d2dd73e3150dbf2aca/CSforDev_L17-ComposableLandingPage.png` |
| CSforDev\_L17-OpenSyperheroLandingPage.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltbd496f6c2aa7c3fb/67dc74d1632b938d87d497f4/CSforDev_L17-OpenSyperheroLandingPage.png` |
| CSforDev\_L17-OpenContentTypeDefinition.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltcb805c91070decc1/67dc74d18fee9a015647d6ce/CSforDev_L17-OpenContentTypeDefinition.png` |
| CSforDev\_L17-GlobalFieldDefinitions.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt133ae7c39bec81dd/67dc74d1782bfb40816f4d07/CSforDev_L17-GlobalFieldDefinitions.png` |
| CSforDev\_L17-CodeForGalleryEntry.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt32ad6ea1b6068a60/67dc74d16f68587885fd9e35/CSforDev_L17-CodeForGalleryEntry.png` |
| CSforDev\_L17-BlockRenderwithNextJScomp.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt6997b78ab65f5110/67dc74d1bbf93ef9c3586444/CSforDev_L17-BlockRenderwithNextJScomp.png` |
| CSforDev\_L17-HeroBannerBlock.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt57deb882be0262c1/67dc74d1db243fda9112b9df/CSforDev_L17-HeroBannerBlock.png` |

### External links

| Label | URL |
| --- | --- |
| Contentstack Academy home | `https://www.contentstack.com/academy/` |
| Training instance setup | `https://www.contentstack.com/academy/training-instance` |
| Academy playground (GitHub) | `https://github.com/contentstack/contentstack-academy-playground` |
| Contentstack documentation | `https://www.contentstack.com/docs/` |
| CSforDev\_L17\_ComposableHeroes.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt36760c2226f23188/67dc74d1443bd6f8bef1c126/CSforDev_L17_ComposableHeroes.png` |
| CSforDev\_L17-HeroGalleryPageContentType.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltca3a395e8b43a268/67dc74d25e486ddf7571ab5f/CSforDev_L17-HeroGalleryPageContentType.png` |
| CSforDev\_L17-SuperHeroGalleryPage.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt5d634d5af8ed1ef2/67dc74d120a3dc7d26f81da5/CSforDev_L17-SuperHeroGalleryPage.png` |
| In the /helpers/index.js file | `https://github.com/contentstack/contentstack-academy-playground/blob/main/helper/index.js` |
| Review the code for the /composable-heroes/index.tsx file | `https://github.com/contentstack/contentstack-academy-playground/blob/main/pages/composable-heroes/index.tsx` |
| CSforDev\_L17-ReviewComposableHeroesGalleryEntry.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blta1719b3c553d3aa7/67dc74d28fee9af26547d6d2/CSforDev_L17-ReviewComposableHeroesGalleryEntry.png` |
| CSforDev\_L17-NextJSappOpenComposableHeroes.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt987109e80668c33d/67dc74d2c566ee77065df700/CSforDev_L17-NextJSappOpenComposableHeroes.png` |
| Content Delivery Query API documentation | `https://www.contentstack.com/docs/developers/apis/content-delivery-api/#queries` |
| CSforDev\_L17-Postman1.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltfc54a08558f3257d/67dc74d20c6f5573391fc550/CSforDev_L17-Postman1.png` |
| Javascript Content Delivery SDK | `https://www.contentstack.com/docs/developers/sdks/content-delivery-sdk/javascript-browser/reference/` |
| documentation for the query methods | `https://www.contentstack.com/docs/developers/sdks/content-delivery-sdk/javascript-browser/reference/#query` |
| SDKs documentation page | `https://www.contentstack.com/docs/developers/sdks/` |
| More information about this is found in the Javascript SDK Docs | `https://www.contentstack.com/docs/developers/sdks/content-delivery-sdk/javascript-browser/reference/#stack-query` |
| Modular Blocks | `https://www.contentstack.com/docs/developers/create-content-types/modular-blocks/` |
| CSforDev\_L17-ComposableLandingPage.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt20cf9dbe38b2ce7a/67dc74d2dd73e3150dbf2aca/CSforDev_L17-ComposableLandingPage.png` |
| CSforDev\_L17-OpenSyperheroLandingPage.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltbd496f6c2aa7c3fb/67dc74d1632b938d87d497f4/CSforDev_L17-OpenSyperheroLandingPage.png` |
