Router w/Page Object Integration Tutorial
How it works:
- Generate a JSON object for each page on CMS publish
- Integrate the CMS Router to enable:
- Loading the JSON object and passing it to a template renderer
- Page URLs anywhere in the site
- Custom Redirects defined in CMS
- Work Involved: Easy to Medium, based on site complexity
Overview:
The Router w/Page Object integration method:
- Serves static content (images, files, and JSON page data) out of a public content folder external to the Next.js application
- Adds a catch-all route to the Next.js application, to serve CMS pages and redirects
Integration:
- In the jsHarmony CMS, on the Sites tab, create a new Site
- Download the jsHarmony Redirects Component and extract into your site's SFTP folder. This contains a "jshcms_redirects.html" component that exports the Redirects as JSON into a file named "jshcms_redirects.json" in the root of the site. A site_config.json file is also included with the "redirect_listing_path" parameter, so that the integration code will be properly generated.
- In the Site Settings, add a Deployment Target:
- Configure the Deployment Target to publish to a location that is publicly accessible from the Next.js application (for example, an S3 bucket, Github Pages, a public website folder, or an Apache virtual subfolder)
- Set the URL Prefix to the publicly accessible URL path where the CMS Content files (HTML, JSON, Images) will be published, for example "https://domain.com/path/"
- Set the "Override Page URL Prefix" to the path prefix for the CMS Page URLs, if different from the CMS Content path.
For example, if URLs will be root-relative, set the Page URL Prefix to "/"
- Generate the Integration Code:
- In the Deployment Target, click on the "Integration Code" tab
- Select the Environment "Next.js - Router" to get the Integration Code
- In your Next.js application, install the "jsharmony-cms-sdk-next" module:
npm install jsharmony-cms-sdk-next
- Create a new catch-all route in Next.js by adding a "src/pages/[[...path]].tsx" file, and paste the Integration Code from step 4 (example below).
* If you are not overriding the home page, you will need to change the file name to "src/pages/[...path].tsx"
import type { GetServerSideProps } from 'next';
import { JshCms, JshCmsRouter, JshCmsPage, JshCmsContentArea } from 'jsharmony-cms-sdk-next'
const jshCmsConfig = {
redirectListingPath: "jshcms_redirects.json",
cmsServerUrls: ["https://cms.example.com/"],
contentUrl: "https://domain.com/path/to/content/"
};
const jshCmsRouter = new JshCmsRouter(jshCmsConfig);
export const getServerSideProps: GetServerSideProps = async(context) => {
return await jshCmsRouter.serve(context.query.path, context.query);
};
export default function Page({ jshCmsPage }: { jshCmsPage: JshCmsPage }) {
return (
<JshCms jshCmsPage={jshCmsPage} jshCmsConfig={jshCmsConfig}>
<h1 cms-title="true">{jshCmsPage?.title||'Title'}</h1>
<JshCmsContentArea cms-content="body">Page Content</JshCmsContentArea>
</JshCms>
);
};
- Add the template to the CMS Site Page Templates
- In the CMS Site Settings, select the "Page Templates" tab
- Add a Remote Page Template, entering a Name, Title, and the full URL to the page, ex. http://localhost:3000/
- Edit the Config for the new Page Template by clicking the pencil icon, and enter the following to export to JSON on publish:
{
"templates": { "publish": "format:json" }
}
* After this step, it should be possible to add and edit pages from the CMS.
- To support multiple templates, make your modify your Page function to select the template based on the page_template_id (which should match the Template Name in the CMS Page Templates tab).
As a simple example, a two-column template can be added to the Page function as below:
export default function Page({ jshCmsPage }: { jshCmsPage: JshCmsPage }) {
if(jshCmsPage.page_template_id == 'two-column'){
// Two Column Template
return (
<JshCms jshCmsPage={jshCmsPage} jshCmsConfig={jshCmsConfig}>
<h1 cms-title="true">{jshCmsPage?.title||'Title'}</h1>
<JshCmsContentArea cms-content="col1">Column 1</JshCmsContentArea>
<JshCmsContentArea cms-content="col2">Column 2</JshCmsContentArea>
</JshCms>
);
}
else {
// Default Template
return (
<JshCms jshCmsPage={jshCmsPage} jshCmsConfig={jshCmsConfig}>
<h1 cms-title="true">{jshCmsPage?.title||'Title'}</h1>
<JshCmsContentArea cms-content="body">Page Content</JshCmsContentArea>
</JshCms>
);
}
};
- In order to publish multiple content areas, such as in a two-column template, modify the "Config" under the CMS Site Settings -> "Page Templates" tab, to define the content areas:
{
"templates":{ "publish":"format:json" },
"content_elements": { "column1": {"title": "Column 1"}, "column2": {"title": "Column 2"} }
}
- Add CMS content and publish to the Deployment Target, generating JSON and image files on the content server