Pages

This article provides details of how Pages can be created and managed in Clutch.

Introduction

Pages define paths and what renders at those paths, creating the site's routing structure. They are crucial for dynamic paths (like a blog article detail page having the article ID/slug in the URL that will be the dynamic segment to pull info from data source) and search parameters (to for example, filtering by search params or determine which page of a paginated page we are on and set how many per page should be shown).

Creating and Managing Pages

Homepage: Every site has a homepage, located at the forward slash (/) path. When a new Project is created in Clutch, it automatically creates the Home page for you.

Any page’s label can be changed by double clicking on its layer in the Navigator and typing the new name.

Page Creation and Navigation: New pages can be created either by duplicating existing pages or via Insert → Pages → Blank page. The keyboard shortcut for duplicating the currently selected page is Ctrl/Cmd + D.

Pages render within the page slot of a layout.

Sitewide header and footer typically come above and below the page slot in the Site layout. This is covered in the earlier Layouts article.

The site navigator facilitates moving between pages. Pages can be re-arranged in the builder by dragging and dropping.

The URL that a page points to can be seen and changed at the right, above the properties panel.

Setting Up Navigation Links

Linking Pages: Links can be added via the Link component’s href property and connected to different pages for navigation.

Only the page content reloads during navigation, not the entire layout.

Page Styling: Different styles can be applied to individual pages, including typography and color schemes.

Page Templates: Pages can be saved as templates for reuse by right-clicking and adding to library. If you later publish the project as a library, any Clutch user that installs your library in their Clutch project will get your page template.

Drafts: Pages can also be set to draft mode, preventing them from being published.

Advanced Page Features

Dynamic Paths and Data Binding: Pages can have dynamic paths, allowing for variable segments in the URL. These dynamic segments can be used to fetch data.

Single/detail page

Example of a dynamic path for a page labelled say, “People”:

/people/[id]

As soon as you click off of a dynamic path input, controls to set the defaults for the segments or dynamic parts will appear automatically, above the Path control.

Let’s say you want to show a Star Wars character on this page from a API, first add a data connection by clicking the Data icon or typing the letter d.

To create a new query using custom code (via AI in this example), click on New Query, and then the code icon to open the project’s src/queries/queries.ts file.

You could open GitHub Copilot chat in your code editor, switch to Edit mode and use this sample prompt:

#fetch https://akabab.github.io/starwars-api/

Create a function to get a person by id

Sample code generated:

/**
 * Fetches a Star Wars character by ID from the Star Wars API.
 *
 * @param id - The ID of the character to fetch
 * @returns A promise that resolves to the character data
 * @throws If there is an error fetching the character
 */
export async function getStarWarsPerson(id: number) {
  const url = `https://akabab.github.io/starwars-api/api/id/${id}.json`;

  const response = await fetch(url, {
    next: {
      revalidate: 3600,
      tags: ['star-wars-person'],
    },
  });

  if (!response.ok) {
    throw new Error('Failed to fetch Star Wars character');
  }

  return await response.json();
}

Save the file and back in Clutch, getStarWarsPerson function will now appear in the Pick Query interface.

Select the new function and put in 1 for testing. It should show the data (fetched from the API) of Star Wars character whose ID is 1.

Now you want to bind this ID to the value from the URL.

Hover near the top left corner of the control and click the green dynamic bolt icon.

Expand Params under Navigation and select id.

Test the functionality in the Play mode (Ctrl/Cmd + p) or in a auto-refreshing new tab if you have the project open in one.

Change /people/1 to /people/2 in the URL to see the data of character whose ID is 2.

Now you are ready to add elements as children inside Data and bind to the dynamic values.

Listing page

Let’s set up a page where a list of Star Wars characters can be seen.

Duplicate the earlier detail page and change its path from /people/[id] to /people.

Back in your code editor, using AI or otherwise write a function to pull in all the characters.

Sample prompt:

Write a function that fetches all characters but with a limit parameter.

Sample function:

Ex.:

/**
 * Fetches all Star Wars characters with an optional limit.
 *
 * @param limit - Optional maximum number of characters to return
 * @returns A promise that resolves to an array of character data
 * @throws If there is an error fetching the characters
 */
export async function getAllStarWarsCharacters(limit?: number) {
  const url = 'https://akabab.github.io/starwars-api/api/all.json';

  const response = await fetch(url, {
    next: {
      revalidate: 3600,
      tags: ['star-wars-characters'],
    },
  });

  if (!response.ok) {
    throw new Error('Failed to fetch Star Wars characters');
  }

  const data = await response.json();
  return limit ? data.slice(0, limit) : data;
}

Set the query to the above function.

Set a limit of say, 4.

You can click Run test button to test if the function is fetching the data correctly.

Let’s now bind the limit to a query parameter by the same name.

In Clutch’s address bar, append ?limit=4 to /people so the URL becomes /people?limit=4.

Select limit search param.

To use/show the fetched data, you’d need to add a Loop (whose data is bound to getAllStarWarsCharacters function) inside Data since we are dealing with a collection of data (having 1 or more items).

Search Parameters: Search parameters can be used to filter and modify data displayed on a page.

Conclusion

  • Pages dictate and create your site map and structure.

  • Pages render inside layout slots.

  • Multiple (nested) layouts can be created.

  • Pages are the only part that reload when navigating.

  • Pages can be kept in draft mode.

  • Pages can be added to library.

  • We can create dynamic segments. The dynamic part of the path can be passed into data functions.

  • We can also create search params that can be passed into data functions.

Additional videos