Building a Blog with Squidex and Next.js
How to Build a Next.js Blog Powered by Content From the Squidex CMS
Last updated
How to Build a Next.js Blog Powered by Content From the Squidex CMS
Last updated
This tutorial guides on creating a blog application, setting up its schema and adding mock content on Squidex. Then, the guide demonstrates how to create a Next.js blog based on the data stored in a CMS.
Here's what's needed to complete this guide:
A Squidex account. Create an account here: https://cloud.squidex.io.
Node.js installed on a computer. Follow this guide to install Node.js if it is not yet installed.
In Squidex, an application is an isolated data store with schemas that defines how its content is structured along with API end points to query its content. Visit this page of the Squidex docs to learn more about Apps in Squidex.
Start by logging into the Squidex account dashboard at https://cloud.squidex.io/. Click New App (1) to create an empty application. Enter a unique Name (2) for the App in the space provided and click Create (3) to create the App. For the purposes of this guide, the Squidex application name is squidex-blog.
App names in Squidex cloud are global, which is why the name must be unique. Add name initials or a word to make it unique.
Now that the App is created on Squidex, let's start creating the schema for the blog application. This schema will define the structure of the blog content.
On the Squidex dashboard, click squidex-blog (or whichever name you've used) to enter the dashboard for the newly created App.
On the left panel, select Schemas (5) and click the Plus(+) (6) button to start creating the posts
schema. Enter posts
in the space provided under Name (7), select Multiple contents (8) as there will be multiple posts and click Create (9) to create the schema.
The posts schema will have 3 fields, i.e. Title
for the title of posts, Slug
to define the URL of posts, and Content
to contain the body of the blog posts.
Field name | Type | Editor |
---|---|---|
Title | String | Input |
Slug | String | Slug |
Content | String | Markdown |
Ensure you are in Posts (11) schema under Schemas (10) and click +Add Field (12) to start adding fields.
In the modal window, select String (13) enter Title
(14) in the field provided and click Create and edit field (15) as shown below:
Click the Validation (16) tab on the new modal window that opens up, then check Required (17). This is needed as every post must have a title, which is why it is a required / mandatory field. Click Save and add field (18) to save changes.
Repeat the steps above to create the remaining two fields i.e, Slug
and Content
.
The Slug
field is configured as shown in the screenshots below:
As every post must have a slug (and it has to be unique), complete the Validation tab in the modal that opens as displayed below:
Finally, switch to the Editing tab and select Slug as the editor (as displayed below). The options in this Editor section allow the choosing of a preferred editor to be used to edit a particular field. Click Save and add field to save the Slug
field and proceed to add the Content
field.
The third field, i.e the Content
field is formatted as Markdown text. Configure the Content
field as displayed below. Click Create and edit field to continue:
Set the Content
field to use a WYSIWYG editor by configuring the Editor to Markdown in the Editing tab as displayed below. Click Save and close to save the changes to the Content
field.
The posts
schema and its fields should now be completed. To add content under the posts
schema, it must be published. Click Published (situated on the top right corner of the page to do so).
Now that the schema is published, sample content can be added to it which will be displayed once the blog is built.
To add content, click Content (1) on the sidebar and select posts (2) if not already selected. Click +New (3) to create a new post.
To transfer existing content to Squidex, just paste it here. It's also possible to manually enter some placeholders for the title, slug and content. Next, click Save and Publish (4) to publish the created content.
Click the back icon to go back to the list of content for the posts' schema, click +New again and repeat the steps for as many posts as desired.
Once the schema is created on Squidex, proceed to set up the Next.js workspace.
Open the terminal and run the following command to install Next.js and its dependencies.
If prompted to confirm installation of the create-next-App package, type y
and press enter to continue with the installation.
Once Next.js is set up, run the following commands to enter the squidex-blog
directory and start the development server.
The yarn dev
command starts a Next.js development server at http://localhost:3000
. Visit htttp://localhost:3000
to see the Next.js App. The text Welcome to Next.js should appear on the page. This confirms successful installation of Next.js and that the system is ready to for a blog to be built.
Start by creating a Layout
component that adds a header and footer to all the pages of the blog. Create a components
folder in squidex-blog
and create a layout.js
file in the squidex-blog/components
folder with the following content:
This creates a header and footer with a link to the blog's homepage. The children
prop allows embedding of whatever content is added into the Layout
component between the header and footer.
After creating the Layout
component, replace the contents of the squidex-blog/styles/globals.css
file with the following:
Now that the website's stylesheet has been modified, continue to modify the custom Next.js App
component of the blog to wrap the application in a header and footer with the Layout
component already created. In Next.js, a custom app component is used to add a consistent layout to App pages and to add global CSS to the App. Learn more about this by reading the Custom App page of the Next.js documentation.
Modify _app.js
in squidex-blog/pages
should have the the following content:
Visit localhost:3000
(if you haven't already). The development server will rebuild the blog and you will be able to see the newly added header and footer.
Now that styles and a header and footer have been added to the application, proceed to set up authentication for requests to the Squidex API.
To be able to fetch data from the Squidex App, create a client on Squidex.
Open the dashboard of the blog application(Squidex-blog or whatever name desired) from https://cloud.squidex.io. On the left sidebar, click the Cog icon at the bottom left corner of the page to open up the settings. Under the Security section click Clients. At the top of the page, there is a section where you can create a client. In the text box provided under Add a New Client, type nextjs-blog
as the name of the client and click Add Client to create the client. When scrolling down the page, notice a new nextjs-blog
client has been created. By default, this new client comes with the Editor role. In Squidex, roles define which schemas a client has access to and which operations (such as reading and writing) a client is authorised to do. As there won't be any changes to your content from the blog's front end, change the role of the client to Reader, i.e. with read-only permissions. In the dropdown for Role, select Reader.
Normally, an access token is required to query the Squidex API, but as the blog application will only be reading data from Squidex (not editing or deleting), simply create an anonymous client. Check the Allow Anonymous Access checkbox to allow this client to query published blog posts without an access token.
Now a new client has been created, and allowed anonymous access to published blog posts, create a file containing environment variables for the Next.js app. Create a .env.local
file in the squidex-blog
folder and add the following content:
Replace <YOUR_APP>
in the value of SQUIDEX_API_URL with the name of your own App on Squidex.
Next.js only loads data from the .env.local
file once, when you start the development server. To load the environment variables created, restart the development server. Press the combination Ctrl/CMD + C
on the terminal to stop the development server, then restart it by running the following:
Note the message in the terminal showing that environment variables have been loaded from .env.local
. Visit the Environment Variables page of the Next.js documentation to learn more about environment variables in Next.js. Now, proceed to create a helper function used to make GraphQL queries to Squidex.
Create a lib
folder in squidex-blog
and in this lib folder, create a squidex.js
file. Add the following content to the squidex-blog/lib/squidex.js
file:
This exports a fetchAPI
function that receives a GraphQL query and its variables (as parameters), queries the Squidex API and returns the result.
Next, fetch content from Squidex and display it in your Next.js blog.
In this step, learn to fetch the titles and links of blog posts and display them on the homepage of your blog.
Replace the content of squidex-blog/pages/index.js
with the following:
Open http://localhost:3000
in your browser (if it is not already open), to continue previewing changes.
At the top of the pages/index.js
file, import the fetchAPI
utility from squidex-app/lib/squidex
:
Also in index.js
, export a getStaticProps
function defined as follows:
This sends a GraphQL query to your Squidex App to get the slugs and titles of all blog posts and returns this data to your page.
In Next.js, getStaticProps
is a function that is run at build time to fetch and store data needed to render a page. To learn more about data-fetching with getStaticProps
in Next.js, see the getStaticProps page of the Next.js documentation. Save the file and refresh the browser to fetch page data from the CMS.
To make this data available to the Home
page component of index.js
, pass posts as a prop to Home
in index.js:
Although the title and slugs of your blog posts are now available to the Home
component, they will not be rendered on the homepage. Create a BlogItem
component that will be used to display and link to all of your posts.
Create a blogItem.js
file in the squidex-blog/components
folder with the following content:
To use BlogItem
on the homepage, import it in pages/index.js
.
And in the Home
function in index.js
, after the Head
tag, add the following:
This loops through blog posts and creates a link to each of them.
The completed index.js
file will look like this:
If you look at your blog homepage in a browser, note that the titles of posts are shown and they link to the page where the article can be read.
Now links to your posts have been successfully created, create a page to display the content of the blog posts.
In the pages
folder, create a [slug].js
file. In Next.js, a page is a React Component file in the pages directory. The component at pages/about.js, for example will be accessible at /about. A page enclosed in square brackets like [slug].js is a fallback and Next.js will show this page for all URLs that are not handled by another page, and will pass a slug
variable to the page. So when you visit a URL like /my-first-blog-post this page is used and slug
will have the value my-first-blog-post.
You can learn more about this from the dynamic routes page of the Next.js documentation..
Click one of the links on the homepage to visit the page where your blog posts will be rendered.
Since you will need to render markdown content on this page, you will install next-mdx-remote, a package that parses markdown content and renders it in your Next.js application. Stop the development server by pressing Ctrl/Cmd + C
on your terminal and run the following command to install next-mdx-remote
:
Restart the development server after installation:
Import serialize
and MDXRemote
from next-mdx-remote
at the top of [slug].js
:
Import fetchAPI
at the top of [slug].js
as you will use it to fetch the contents your blog posts from Squidex:
Export a getStaticProps
function from [slug].js
:
This returns data for the blog post associated with a particular slug or returns a 404 error if no such post exists.
At this point, you may receive an error because when you use getStaticPaths
with dynamic paths in Next.js, you are required to also export a getStaticPaths
function that tells Next.js what pages to generate at build time.
Export a getStaticPaths
function in squidex-blog/pages/[slug].js
:
The Next.js development server only runs getStaticProps
to fetch the page data when the page is initally loaded. So, to preview the changes made to getStaticProps
, you will refresh the page. When you do so, the data will be made available but since it has not been rendered, nothing will be visible. You will now proceed to render the blog post on this page.
Modify the BlogPost
function in [slug].js
:
Once you save the file, the title of the blog post and the body of the post will be rendered on the page. If you did not refresh the page after adding getStaticProps
, you may see an error because the page data has not been loaded. Refresh the page to fetch data from your Squidex application.
The finished [slug].js
file will look like this:
Congratulations! You have now built a fully functional blog in Next.js that sources data from Squidex.
Now that you have built your blog with Next.js and Squidex, learn how to deploy your blog to a live site. Check out this page on Deploying a Next.js site. You may also want to explore the Next.js Head component to see how adding meta tags to your pages enables search engines to better understand your content.