Summary
This article explains how to use AWS Amplify
to manage a blog by creating, updating, and deleting new posts. In contrast to the previous blog post that used MDX files
, this article uses a table on AWS DynamoDB
and a graphical interface to update content. The article covers how to launch Amplify Studio
, create a post data model using Data Modeling, and how to pull resources. Additionally, it demonstrates how to integrate Amplify libraries with Next.js for server-side rendering (SSR)
and provides code examples for fetching and rendering blog posts from the DataStore.
Following the series of articles about AWS Amplify, in this post, we will cover a way to manage our blog by adding a way to create, update, and delete new posts.
In our past blog, we used MDX files to get the markdown content and use Tailwind/Topography prose plugins to show our markdown with tons of beautiful styles.
For this blog, instead of using MDX files to get our markdown content, we will use a table on AWS DynamoDB and a graphic interface to update our content.
Prerequisites
Before proceeding with this article, make sure you have an existing project hosted using AWS Amplify. If you don't have a project yet, you can follow this blog to learn how to host a project using Amplify.
Launching Amplify Studio
To get started, we need to launch Amplify Studio, which is a visual interface that manages the backend resources created by Amplify.
1. Go to the AWS Console and navigate to Amplify services.
2. Select your app, and under backend environments
, click on the yellow button labeled Launch Studio.
Once Amplify Studio is launched, you will see the homepage where you can create or manage different resources. This interface provides a more convenient way to manage data models compared to using the Amplify CLI.
Data Modeling
Now let's create the data model for our blog posts using Amplify Studio.
1. Click on the Data link in the left menu.
2. Click on Add model to create a new model.
3. Enter the model title as Posts.
4. Add the following columns: title, content, and summary.
After defining the model, click on Save and Deploy to deploy the infrastructure.
Wait for a few minutes until Amplify has finished creating all the necessary resources. Once completed, you will see the configuration and instructions for pulling that configuration. Here, you can select the model, operation, and language to generate code for accessing and managing your data.
Create Initial Content
Now, on the Amplify Studio
home page go to*Content
* on the left menu. Here you will be able to create new post and see the list of post that has been created.
Note: There is currently a report that the new data manager doesn't support markdown editor anymore, but there is a work around provided by amplify team until this is resolved:
https://github.com/aws-amplify/amplify-studio/issues/815
And add some markdown
content:
Pull resources
Once we have successfully deployed our infrastructure, you can download the configuration locally using AWS Amplify CLI:
$ amplify pull --appId ddxxxxxxxir --envName dev
Pre-pull status:
Current Environment: dev
┌──────────┬────────────────┬───────────┬───────────────────┐
│ Category │ Resource name │ Operation │ Provider plugin │
├──────────┼────────────────┼───────────┼───────────────────┤
│ Hosting │ amplifyhosting │ Create │ │
├──────────┼────────────────┼───────────┼───────────────────┤
│ Api │ albacdev │ No Change │ awscloudformation │
└──────────┴────────────────┴───────────┴───────────────────┘
⚠️ Local changes detected.
⚠️ Pulling changes from the cloud will override your local changes.
Now you are ready to start coding and use your data model storage.
The Code
In our previous implementation, we used MDX files
stored in a GitHub repository to display our markdown content as a web blog page. However, this approach made it challenging to manage and maintain the MDX files through a website. It required downloading, editing, and re-uploading the MDX files.
To improve the management of our blog posts, we can leverage the Amplify libraries
for a more efficient workflow.
- aws-amplify: This is the core library of AWS Amplify, providing a JavaScript interface for interacting with AWS services, including authentication, storage, and database.
- @aws-amplify/ui-react: This library offers UI components and utilities for building user interfaces in React applications. It includes components for authentication, forms, and commonly used web application UI elements.
These libraries simplify the integration of AWS services into React applications, providing convenient methods and components for tasks like authentication and data management. They abstract the underlying AWS SDKs, offering a higher-level API that streamlines the development process.
To implement this solution, we can also take advantage of the Next.js server-side rendering (SSR)
feature supported by the Amplify libraries.
First, make sure you have the necessary Amplify UI libraries
by running the following command:
$ npm install aws-amplify @aws-amplify/ui-react
Next, update your _app.js
file to configure Amplify and enable SSR support:
import { Amplify } from 'aws-amplify';
import awsconfig from '../src/aws-exports';
Amplify.configure({
...awsconfig,
ssr: true
});
In your [slug.js]
file, make the following changes:
+import { withSSRContext } from "aws-amplify";
+import { Posts } from "../../src/models";
import { format, parseISO } from "date-fns"
export async function getStaticProps(context) {
+ const { DataStore } = withSSRContext(context);
const { params } = context;
- const allPosts = getAllPosts();
- const { data, content } = allPosts.find((item) => item.slug === params.slug);
+ const { slug } = params;
+ const post = await DataStore.query(Posts, slug);
+ const { data, content } = matter(post.content);
+ console.log(data, content);
const mdxSource = await serialize(content);
return {
props: {
...data,
- date: data.date.toISOString(),
+ date: post.createdAt,
content: mdxSource,
},
+ revalidate: 60 * 60,
};
}
-export async function getStaticPaths() {
+export async function getStaticPaths(context) {
+ const { DataStore } = withSSRContext(context);
+ const posts = await DataStore.query(Posts);
+ const paths = posts.map((post) => ({ params: { slug: post.id } }));
return {
- paths: getAllPosts().map((post) => ({
- params: {
- slug: post.slug,
- },
- })),
- fallback: false,
+ paths,
+ fallback: true,
};
}
Let's break down the changes:
import { withSSRContext } from "aws-amplify";
import { Posts } from "../../src/models";
Here, we import the withSSRContext
function, which enables us to query our data using SSR, and the Posts
schema from the GraphQL models.
export async function getStaticProps(context) {
const { DataStore } = withSSRContext(context);
const { params } = context;
const { slug } = params;
const post = await DataStore.query(Posts, slug);
const { data, content } = matter(post.content);
const mdxSource = await serialize(content);
We utilize the getStaticProps
function from Next.js, which receives the context
object containing the req
and res
keys from the session.
Using context
, we leverage withSSRContext
from Amplify to obtain the DataStore
function. We also extract the parameters and the slug
, which represents the ID of our post request. With the slug
and DataStore.query
function, we fetch the data and assign it to the post
variable. From post
, we can retrieve all the relevant post details such as the content, date, and summary.
return {
props: {
...data,
date: post.createdAt,
content: mdxSource,
slug: slug,
},
revalidate: 60 * 60,
};
Finally, we return the data for rendering. The revalidate
property is used to generate the data on the server-side according to the specified schedule.
In the future we will like to use on On-Demand Incremental Static Regeneration (ISR) but at the moment is not a supported feature: https://docs.aws.amazon.com/amplify/latest/userguide/ssr-Amplify-support.html
The same modifications are made to the getStaticPaths
function for generating the paths:
export async function getStaticPaths(context) {
const { DataStore } = withSSRContext(context);
const posts = await DataStore.query(Posts);
const paths = posts.map((post) => ({ params: { slug: post.id } }));
return {
paths,
fallback: true,
};
}
With these changes in place, you can render the post as before, but now utilizing the Post
model datastore instead of static files.
<div className="mx-5">
<h2 className="dark:text-white text-3xl mt-8 font-bold">
{title}
</h2>
<div className="text-sm text-gray-600 dark:text-gray-200 mt-4">
Published {format(parseISO(date), "MMMM do, uuu")}
</div>
<article
className="
+ prose dark:prose-invert
+ prose-a:text-blue-600
+ prose-a:font-light
+ prose-a:italic
+ prose-pre:bg-slate-800
+ prose-img:rounded
+ xl:prose-pre:prose-md
+ lg:prose-pre:prose-sm
+ xl:prose-xl
+ lg:prose-lg
+ prose-xl
+ max-w-sm
+ sm:max-w-lg
+ md:max-w-2xl
+ lg:max-w-3xl
+ xl:max-w-5xl
+ 2xl:max-w-5xl
+ lg:prose-img:max-w-5xl
+ pt-6 text-slate-600 dark:text-slate-300 font-light font-sans"
>
<MDXRemote {...content} />
</article>
</div>
You can find the complete code here.
Finally, once you update a blog on Amplify Studio, depending of the revalidation time, the content of the blog will be recreated from our database and show in our website.
Conclusion
In the context of this blog, DynamoDB is used as the data store for the blog posts. Instead of using MDX files, the blog content is stored in a DynamoDB table, which is accessed and managed using Amplify Studio. This approach provides an easy way to manage blog content without having to deal with the complexities of file-based storage.
In summary, AWS Amplify is a powerful development platform that provides a wide range of services and features for building modern web and mobile applications. Amplify Studio is a visual interface that simplifies the process of managing backend resources, making it an ideal choice for developers who prefer a more visual approach. Next.js is a popular React-based framework that offers several features for building server-side rendered web applications. AWS DynamoDB is a highly available, durable, and secure NoSQL database service that provides fast and predictable performance with seamless scalability.
References
- Nadder Dabit GitHub(Popular AWS/Next.js/Web3 developer): https://github.com/dabit3/next.js-amplify-datastore
- Official Amplify documentation for DataStore: https://docs.amplify.aws/lib/datastore/data-access/q/platform/js/
- AWS Amplify Next.js feature support: https://docs.aws.amazon.com/amplify/latest/userguide/ssr-Amplify-support.html
- Author's portfolio blog: https://albac.dev/blog/67d0470b-4056-460c-9272-3b182d4ab8aa
- Blog code: https://github.com/albac/albac.dev/blob/v1.3/
Top comments (0)