I am stuck on this problem for many days. I am using Next.js and have 3 pages.
- pages/index.js
- pages/categories.js
- pages/categories/[slug].js
The categories/[slug].js
is using Next.js fetching method name getServerSideProps that runs on each request and used for build dynamic pages on runtime. The categories/[slug].js
is rendering a dynamic content on the page that dynamic content comes from the CMS as a response from the API Endpoint. Dynamic content is nothing but a string that contains HTML with <script />
elements.
Note: To fetch the content from the CMS we have to send a POST
request with the CMS
credentials like username, password, and the page slug for the content. I am using axios library to send a post request and the method is inside post.js
file.
post.js:
import axios from 'axios';
const postCMS = async (slug) => {
const url = `${process.env.CMS_API_URL}/render-page/`;
let pageSlug = slug;
// If the pageSlug is not start with `/`, then create the slug with `/`
if (!pageSlug.startsWith('/')) {
pageSlug = `/${pageSlug}`;
}
const head = {
Accept: 'application/json',
'Content-Type': 'application/json'
};
const data = JSON.stringify({
username: process.env.CMS_API_USERNAME,
password: process.env.CMS_API_PASSWORD,
slug: pageSlug
});
try {
const response = await axios.post(url, data, {
headers: head
});
return response.data;
} catch (e) {
return e;
}
};
export default postCMS;
But for the rendering content on the categories/[slug].js
page, I am using the Reactjs prop name dangerouslySetInnerHTML to render all the HTML which also contains <script />
elements in the JSON string.
pages/categories/[slug].js:
<div dangerouslySetInnerHTML={{ __html: result.html }} />
The content is loading fine based on each slug. But when I navigate to that category page i.e.pages/categories/index.js
.
<Link href="/categories/[slug]" as="/categories/online-cloud-storage">
<a>Online Cloud Storage</a>
</Link>
It has a <Link />
element and when I click it.
The dynamic content is loading fine but that dynamic content contains accordion
and slider
elements they are not working. I think <script />
of these elements is not working. But when I refresh the page they work fine. See this.
They also work fine when I set the Link something like this.
<Link href="/categories/online-cloud-storage" as="/categories/online-cloud-storage">
<a>Online Cloud Storage</a>
</Link>
But after setting the link like the above method, the click is caused to hard reload the page. But I don't want this. Everything should work. When the user clicks on the category link.
Is there a way to fix this?
Why the content elements are not working when you click from the categories/index.js
page?
Code:
pages/index.js:
import React from 'react';
import Link from 'next/link';
const IndexPage = () => {
return (
<div>
<Link href="/categories">
<a>Categories</a>
</Link>
</div>
);
};
export default IndexPage;
pages/categories/index.js:
import React from 'react';
import Link from 'next/link';
const Categories = () => {
return (
<div>
<Link href="/categories/[slug]" as="/categories/online-cloud-storage">
<a>Online Cloud Storage</a>
</Link>
</div>
);
};
export default Categories;
pages/categories/[slug].js:
import React from 'react';
import Head from 'next/head';
import postCMS from '../../post';
const CategoryPage = ({ result }) => {
return (
<>
<Head>
{result && <link href={result.assets.stylesheets} rel="stylesheet" />}
</Head>
<div>
<h1>Category page CMS Content</h1>
<div dangerouslySetInnerHTML={{ __html: result.html }} />
</div>
</>
);
};
export const getServerSideProps = async (context) => {
const categorySlug = context.query.slug;
const result = await postCMS(categorySlug);
return {
props: {
result
}
};
};
export default CategoryPage;