Client-side routing for dynamic pages

Frontastic uses the Next.js router for client-side routing, making it simple to create links to any dynamic pagedynamic page - A type of page that creates the default layout of pages that use the same structure but with different data, for example, a Product Details Page, wishlist, cart, search, and so on. Previously known as `master page`. as long as the dynamic-page-handler has the logic to handle the created links.

In this article, we'll see how to create a dynamic pagedynamic page - A type of page that creates the default layout of pages that use the same structure but with different data, for example, a Product Details Page, wishlist, cart, search, and so on. Previously known as `master page`. and link it to other pages on the frontend.

Let's modify our Star Wars example by adding 2 new pages:

  • A static page /star-wars/films showing a list of all the Star Wars films
  • A dynamic pagedynamic page - A type of page that creates the default layout of pages that use the same structure but with different data, for example, a Product Details Page, wishlist, cart, search, and so on. Previously known as `master page`. /star-wars/film/[filmId] showing the details of the Star Wars film with filmId

Before we get started, create a sandbox in your Frontastic studioFrontastic studio - The interface you use to manage, build, and edit all areas of your project and commerce sites. Previously known as `backstage`. project and use this Frontastic sandboxFrontastic sandbox - A virtual machine hosted in the cloud that you can use for backend and some frontend development. They're provisioned from the developer area of the Frontastic studio. instance for the local development.

Creating the film details page

  1. Add the logic to grab the filmId from the URL pattern /star-wars/film/[filmId] so it can be used to fetch the film information from SWAPI, to the dynamic-page-handler present in the backend/index.ts file
'dynamic-page-handler': async (request: Request): Promise<DynamicPageSuccessResult | null> => {
    const [_, filmId] = request.query.path.match(new RegExp('/star-wars/film/([^ /]+)'));
    if (filmId) {
      return await axios
        .post<DynamicPageSuccessResult>('https://swapi-graphql.netlify.app/.netlify/functions/index', {
          query: '{film(id:"' + filmId + '") {id, title, openingCrawl, releaseDate}}',
        })
        .then((response): DynamicPageSuccessResult => {
          return {
            dynamicPageType: 'example/star-wars-film-page',
            dataSourcePayload: response.data,
            pageMatchingPayload: response.data,
          };
        })
        .catch((err) => {
          return {
            dynamicPageType: 'example/star-wars-film-page',
            dataSourcePayload: { err },
            pageMatchingPayload: { err },
          };
        });
    }
    return null;
  },
  1. Create a custom Frontastic componentFrontastic component - A customizable building block that's used together with other components to create a commerce site. Known as `tastic` for short in code. in frontend/frontastic/tastics/star-wars/film/ with the following schemaschema - The framework behind a Frontastic component and the fields that are available within the Frontastic studio.
{
    "tasticType": "example/star-wars-film",
    "name": "Star wars movie",
    "icon": "list",
    "category": "Documentation Examples",
    "schema": [
        {
            "name": "Configuration",
            "fields": [
                {
                    "label": "film",
                    "field": "film",
                    "type": "dataSource",
                    "dataSourceType": "example/star-wars-film",
                    "required":true
                }
            ]
        }
    ]
}
  1. Upload this component schemaschema - The framework behind a Frontastic component and the fields that are available within the Frontastic studio. to the Components area of the Frontastic studioFrontastic studio - The interface you use to manage, build, and edit all areas of your project and commerce sites. Previously known as `backstage`.
  1. Create a React component in the tastics/star-wars/film/index.tsx that displays the film data passed to the page by the dynamic-page-handler
import React from 'react';

const StarWarsFilmDetails = ({ data }) => {
  const film = data.data.film || {};
  return (
    <div>
      <h2>{film.title}</h2>
      <p> {film.openingCrawl}</p>
      <p>Released on {film.releaseDate}</p>
    </div>
  );
};

export default StarWarsFilmDetails;
  1. Register StarWarsFilm component in the tastics/index.tsx file
import NotFound from './not-found';
import Markdown from './markdown/tastic';
import StarWarsFilm from './star-wars/movie';

export const tastics = {
  default: NotFound,
  'example/star-wars-film': StarWarsFilm,
  'training/content/markdown': Markdown,
};
  1. Create a dynamic pagedynamic page - A type of page that creates the default layout of pages that use the same structure but with different data, for example, a Product Details Page, wishlist, cart, search, and so on. Previously known as `master page`. schemaschema - The framework behind a Frontastic component and the fields that are available within the Frontastic studio. and upload it to the Developer > Dynamic pages section on the Frontastic studioFrontastic studio - The interface you use to manage, build, and edit all areas of your project and commerce sites. Previously known as `backstage`.
{
    "dynamicPageType": "example/star-wars-film-page",
    "name": "Star wars film",
    "category": "Documentation Example",
    "icon": "stars",
    "dataSourceType": "example/star-wars-film",
    "isMultiple": true
}

🚧

You need to use the Production environment while creating the dynamic page.

  1. Go to the Dynamic pages section, select Star wars film, and create a New page version (testbed) in the Default page rule
  1. Use the Star Wars film component on the testbed page version as shown below
  1. Open http://localhost:3000/star-wars/film/ZmlsbXM6Mg==, and the film detail page should open up as shown below

Now that the /star-wars/film/filmId page is working, let's create the star-wars/films page to list links to all films.

Creating the films list page

You need a data sourcedata source - The data provided from an API to display products, content, or anything from an integration or extension. A data source filter is created and can be selected for a Frontastic component that will display the data source filter on your commerce site. extensionextension - Data connectors that you add specifically to your project. to fetch the list of movies from the SWAPI and a custom Frontastic componentFrontastic component - A customizable building block that's used together with other components to create a commerce site. Known as `tastic` for short in code. to render the list of movies for the films page.

  1. Create the schemaschema - The framework behind a Frontastic component and the fields that are available within the Frontastic studio. for the data sourcedata source - The data provided from an API to display products, content, or anything from an integration or extension. A data source filter is created and can be selected for a Frontastic component that will display the data source filter on your commerce site.
{
    "customDataSourceType": "example/star-wars-all-films",
    "name": "Star wars all films",
    "category": "Content",
    "icon": "source",
    "schema": []
}
  1. Upload the data sourcedata source - The data provided from an API to display products, content, or anything from an integration or extension. A data source filter is created and can be selected for a Frontastic component that will display the data source filter on your commerce site. schemaschema - The framework behind a Frontastic component and the fields that are available within the Frontastic studio. to the Developer > Data sources section in the Frontastic studioFrontastic studio - The interface you use to manage, build, and edit all areas of your project and commerce sites. Previously known as `backstage`.
  1. Implement the data sourcedata source - The data provided from an API to display products, content, or anything from an integration or extension. A data source filter is created and can be selected for a Frontastic component that will display the data source filter on your commerce site. extensionextension - Data connectors that you add specifically to your project. in the backend/index.ts file
'example/star-wars-all-films': async (
      config: DataSourceConfiguration,
      context: DataSourceContext,
    ): Promise<DataSourceResult> => {
      return await axios
        .post<DataSourceResult>('https://swapi-graphql.netlify.app/.netlify/functions/index', {
          query: '{allFilms { films {id, title, episodeID}} }',
        })
        .then((response) => ({
          dataSourcePayload: response.data,
        }))
    }
  1. Create a schema.json for the Frontastic componentFrontastic component - A customizable building block that's used together with other components to create a commerce site. Known as `tastic` for short in code. in frontend/frontastic/tastics/star-wars/all-films/ and specify the data sourcedata source - The data provided from an API to display products, content, or anything from an integration or extension. A data source filter is created and can be selected for a Frontastic component that will display the data source filter on your commerce site. you created earlier in the schema field
{
    "tasticType": "example/star-wars-all-films",
    "name": "Star wars films",
    "icon": "list",
    "category": "Documentation Examples",
    "schema": [
        {
            "name": "Configuration",
            "fields": [
                {
                    "label": "films",
                    "field": "films",
                    "type": "dataSource",
                    "dataSourceType": "example/star-wars-all-films",
                    "required": true
                }
            ]
        }
    ]
}
  1. Upload this component schemaschema - The framework behind a Frontastic component and the fields that are available within the Frontastic studio. to the Components section of the Frontastic studioFrontastic studio - The interface you use to manage, build, and edit all areas of your project and commerce sites. Previously known as `backstage`.
  1. Implement the React component in the index.ts, which renders links from the array of films provided by the data sourcedata source - The data provided from an API to display products, content, or anything from an integration or extension. A data source filter is created and can be selected for a Frontastic component that will display the data source filter on your commerce site. extensionextension - Data connectors that you add specifically to your project.
import React from 'react';
import Link from 'next/link';

const StarWarsFilms = ({ data }) => {
  return (
    <div className={'pt-4'}>
      <h3 className={'mb-4'}>Star wars films</h3>
      {data.films.dataSource.data.allFilms.films.map((film) => (
        <Link key={film.id} href={`/star-wars/film/${film.id}`}>
          <a className={'block underline'}>{film.title}</a>
        </Link>
      ))}
    </div>
  );
};

export default StarWarsFilms;
  1. Register this component in the tastics/index.tsx file
import NotFound from './not-found';
import Markdown from './markdown/tastic';
import StarWarsFilms from './star-wars/all-films';
import StarWarsFilm from './star-wars/film';

export const tastics = {
  default: NotFound,
  'example/star-wars-all-films': StarWarsFilms,
  'example/star-wars-film': StarWarsFilm,
  'training/content/markdown': Markdown,
};
  1. From the Frontastic studioFrontastic studio - The interface you use to manage, build, and edit all areas of your project and commerce sites. Previously known as `backstage`., create a New page folder called Star wars and add a New page folder to it called films
  1. Create a New page version with the name films as shown in the image above and use the StarWarsFilms component along with the example/star-wars-all-films data sourcedata source - The data provided from an API to display products, content, or anything from an integration or extension. A data source filter is created and can be selected for a Frontastic component that will display the data source filter on your commerce site. filter
  1. Open http://localhost:3000/star-wars/film/ZmlsbXM6Mg==, and the film detail page should open up as shown below

Let's see the complete flow in action:


Did this page help you?