Build a Blog with Angular and Contentful
I have built a blog application using Angular and a headless CMS, Contentful. Contentful gives developers and non-developers alike the ability to manage content in a web application. I use Contentful to manage content on my website. — I am not sponsored by Contentful and any headless CMS could be substituted. See alternatives [1]
Summary
- What is a Headless CMS
- Contentful Basics
- Angular: Accessing & Displaying Content
- Hosting
What is a Headless CMS
As I learned to build web applications, I heard about Content Management Systems (CMS); such as Wordpress or Drupal. I thought to myself, why would a developer use this if they already knew how to build a website? At the time, I did not understand the need or use-case.
Later, when I was ready to create my own side-projects and ship them to non-developers, I paused.
How can someone, who is not a developer, update content on my web application?
I had already spent a significant amount of time developing my skill set building front-end applications. Would I now have to learn something like WordPress to build apps?
Headless CMS has entered the chat.
Headless CMS, like Contentful, are essentially web applications that abstract away the database/backend from developers and non-developers alike.
A headless CMS does not provide a front-end. — They do provide developers with an API to get content from the back-end, and a user interface for non-developers to enter content into the back-end.
We will build an Angular application to display data and use Contentful to create/manage that data.
Contentful Basics
We will cover the basics of Contentful. — For a comprehensive introduction see here [2].
As an example, let’s set up a new Space with a Single Content Type in five steps.
1. Create a Space
Getting started is as simple as signing up. — Once signed up, we can create our own Space. As an analogy, we can think of a Space like our own individual database.
2. Create a Content Type
We will add a Content Type to our Space. We can think of a Content Type like a table definition in a Database. — A Content Type is not the actual content, just the design.
3. Create Fields
Now we will add fields to our Content Type. Think of fields like columns in a database table. — In our example, we are creating a blog post, which will have fields such as title, description, body, etc…
4. Create Content
Each piece of Content we add will be similar to a new row in a database. We will fill out each field we defined earlier in our blogPost Content Type.
5. Access the API
In the next section, we will use our Space ID and Content Delivery Access Token to retrieve our Contentful data and display it in our application.
Angular: Accessing & Displaying Content
To get started with the Contentful API, we add the following object to our environment.ts file. We enter the information from step 5 of Contentful Basics.
1. Display All Entries of a Content Type
Using cdaClient.getEntries(content_type), we retrieve a promise containing all Content for a specific Content Type. The resolved data is an array of blog posts. Each entry has two properties, fields and sys.
Sys contains information such as created-date and ID. Fields are the fields we defined in step 3 of Contentful Basics.
Leveraging the Angular Structural Directive, *ngFor, we can dynamically add all blog posts to the DOM. — When we add a new blog post to Contentful, our post will be automatically added by our Contentful Service.
Using Angular Template Syntax, we can build list items displaying info from our Contentful Service such as createdAt, ID, title, description, etc…
2. Display a specific Entry of a Content Type
Using cdaClient.getEntry(id), we can query a specific entry from our Contentful data. The resolved data is a single blog post with the sys and fields properties.
When a user clicks one of the containers from the first section, the router navigates to a dynamic route /posts/:id. In snippet 1.2, we passed the ID as a parameter via routerLink.— We can retrieve the ID from Angular’s ActivatedRoute paramMap.
Contentful provides a Markdown editor for all text fields. We will leverage this by converting the Markdown to HTML and setting the inner HTML on a div. [4]
Use innerHTML judiciously, If we do not have full control over what is being entered into the innerHTML we need to sanitize the input to prevent xss-attacks [5].
Using Angular’s Structural Directive, *ngIf, we can optionally display a field if it exists. In our example, we will display a link to an original publication if present.
3. Add a New Contentful Entry
After publishing a new Contentful Entry, our application is immediately updated on refresh with the latest Content. — No changes are needed to our Angular project.
Hosting
The live demo is hosted with Firebase. For directions on hosting a project with Firebase see here [6]. For alternative forms of hosting see here [7].
I am not affiliated with or sponsored by Firebase or any of the alternatives.
Resources & References
[1] Sanity | FlameLink | Headless Wordpress
[4] Learned the Markdown-to-HTML Technique on fireship
[5] DOM Sanitizer
[7] Netlify | AWS | Digital Ocean