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 withfilmId
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
- 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 thedynamic-page-handler
present in thebackend/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;
},
- 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
}
]
}
]
}
- 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`.


- Create a React component in the
tastics/star-wars/film/index.tsx
that displays the film data passed to the page by thedynamic-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;
- Register
StarWarsFilm
component in thetastics/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,
};
- 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.


- Go to the Dynamic pages section, select Star wars film, and create a New page version (testbed) in the Default page rule


- Use the Star Wars film component on the testbed page version as shown below


- 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.
- 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": []
}
- 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`.


- 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,
}))
}
- 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. infrontend/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 theschema
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
}
]
}
]
}
- 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`.


- 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;
- 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,
};
- 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 calledfilms


- Create a New page version with the name
films
as shown in the image above and use theStarWarsFilms
component along with theexample/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


- 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:
Updated 10 days ago