Strapi
Published in

Strapi

Build an Editorial Website with vanilla JavaScript and Strapi

In this tutorial, you will learn how to create an editorial website using Strapi and vanilla JavaScript.

Goals

By the end of this tutorial, you should have learned how to:

  1. Install a Strapi application.
  2. Create an article content type.
  3. Add sample articles to display.
  4. Clone an editorial starter app and configure it.
  5. Fetch and display a single article or a list of articles from Strap on an editorial app.
  6. Display markdown content on a HTML page.

Prerequisites

To build this project, you will need:

  1. Node.js v14.x or lower. Strapi requires it as a dependency. You can get a v14.x release from the Node.js releases page. Pick an appropriate installer for your OS.
  2. the Strapi CLI installed. You will need this to create a Strapi Strapi app and generate APIs and components. You can get it by running:
npm i strapi -g
  1. Git installed. You will need this to clone the editorial app starter. This guide explains how to install it on your specific operating system.
  2. Basic knowledge of JavaScript and Markdown. You can learn more about JavaScript from this basics tutorial and Markdown from this extensive guide.

Step 1 — Install and Set Up a Strapi Application

In this step, you will install the Strapi app and set up an administrator account on its admin panel. The Strapi app will be named editorial-strapi-app. To create the Strapi app, switch directories to where you’d like the app to reside. Run the following command on your terminal:

strapi new editorial-strapi-app --quickstart
Strapi Sign Up Page to create an administrator account
Strapi Admin Panel

Step 2 — Generate the Article API

To create an article on Strapi, you first need to set up a content type for it. In this step, you will not only create an article content type but generate a whole API for it. First, you need to decide what attributes the article content type will have. For this tutorial, it will have 5:

mkdir -p components/tag && touch components/tag/tags.json
{
"collectionName": "components_tag_tags",
"info": {
"name": "Tags",
"icon": "tags",
"description": ""
},
"options": {},
"attributes": {
"name": {
"type": "string",
"required": true,
"unique": true
}
}
}
strapi generate:api article content:richtext title:string description:text
{
"kind": "collectionType",
"collectionName": "articles",
"info": {
"name": "article",
"description": "Articles for the editorial site"
},
"options": {
"increments": true,
"timestamps": true,
"draftAndPublish": true
},
"pluginOptions": {},
"attributes": {
"content": {
"type": "richtext",
"required": true
},
"cover_image": {
"model": "file",
"via": "related",
"allowedTypes": [
"images"
],
"plugin": "upload",
"required": true,
"pluginOptions": {}
},
"description": {
"type": "text",
"required": true
},
"tags": {
"type": "component",
"repeatable": true,
"component": "tag.tags"
},
"title": {
"type": "string",
"required": true,
"unique": true
}
}
}
npm run develop

Step 3 — Make Article Routes Public

When you generate the article API, six routes are created. These routes expose functionality to:

- create an article
- update an article
- delete an article
- return an article using its ID
- return all articles
- return a count of articles.
  1. To begin, log on to the admin panel.
  2. Follow this link to the Public Roles settings. You can also find it under the Users and Permissions Plugin settings. All these are on the Settings page.
  3. Under the Permissions section, look for the Application Subsection.
  4. Under the Article category, select the findone and find checkboxes.
  5. Then click the bright green Save button in the top right corner of the page.
Strapi Article Routes Permission Settings

Step 4 — Add Sample Articles

In this step, you will create sample articles that the public API routes will return. You will do this by:

  1. Going to the Create an entry article form.
  2. Enter all the fields with sample data. Keep in mind that:
  3. All the fields are required apart from tags. So you cannot create an entry without all of them specified.
  4. You can use this lorem ipsum markdown generator if you’d like sample content for your article. You can copy the markdown from that page and add it to the content field.
  5. Once you’re done entering all the fields, click the bright green Save button in the top right corner of the form.
Article Entry Creation Form

Step 5 — Clone the Editorial Site Starter

The editorial site that will display the articles is made from HTML, CSS, and vanilla JavaScript. No framework will be used in it. In this step, you will clone a starter editorial app from Github that contains all the styling and HTML markup. All you will have to do in the subsequent steps is to add the vanilla JavaScript files to fetch the articles from Strapi.

git clone https://github.com/zaracooper/editorial-app.git
cd editorial-app
git checkout starter
npm install
npm run dev

Step 6 — Add an Article List

The home page, index.html, displayed at http://localhost:3000 is pretty bare. During this step, you will fetch the articles from http://localhost:1337/articles and display them on the home page.

  • fetchArticles() which fetches articles from the Strapi /articles route.
  • createArticleCard() which creates a card on the home page for each article.
// scripts/index.js
function fetchArticles() {
const articlesReq = new Request('http://localhost:1337/articles');

fetch(articlesReq)
.then(response => response.json())
.then(articles => {
let articleList = document.getElementById("article-list");

articles.forEach(article => {
articleList.appendChild(createArticleCard(article));
});
});
}

function createArticleCard(article) {
let card = document.createElement("div");
card.classList.add("card");
card.onclick = () => {
window.location.replace(`/pages/article.html?id=${article.id}`)
};

let cardImage = document.createElement("img");
cardImage.classList.add("card-img");
cardImage.src = `http://localhost:1337${article.cover_image.formats.thumbnail.url}`;

let cardBody = document.createElement("div");
cardBody.classList.add("card-body");

let articleTitle = document.createElement("p");
articleTitle.classList.add("card-title");
articleTitle.innerHTML = article.title;

let articleDescription = document.createElement("div");
articleDescription.classList.add("card-description");
articleDescription.innerHTML = article.description;

let articleTags = document.createElement("div");
articleTags.classList.add("article-tag-cont");

let tag;

article.tags.forEach(tg => {
if (tg.name) {
tag = document.createElement("span")
tag.classList.add("article-tag");
tag.innerHTML = tg.name;

articleTags.appendChild(tag);
}
});

cardBody.append(articleTitle, articleDescription, articleTags);

card.append(cardImage, cardBody);

return card;
}

fetchArticles();
Editorial App Home Page

Step 7 — Fetch a Single Article

The last thing to do is display the content of an article. Using the id passed as a query parameter, you will fetch the article from the Strapi app. You will then convert the markdown content to HTML and add it to the page.

// scripts/article.js
function checkForArticle() {
const urlParams = new URLSearchParams(window.location.search);
const articleId = urlParams.get('id');

if (articleId) {
getArticle(articleId);
} else {
showMissingArticleMsg("An article can't be retrieved without an ID.");
}
}

function getArticle(id) {
const articleReq = new Request(`http://localhost:1337/articles/${id}`);

fetch(articleReq)
.then(resp => {
if (resp.ok) {
return resp.json();
} else {
throw new Error(resp.statusText);
}
})
.then(displayArticle)
.catch(showMissingArticleMsg);
}

function displayArticle(article) {
document.getElementById("article-img").src = `http://localhost:1337${article.cover_image.url}`;

document.getElementById("article-title").innerHTML = article.title;

document.getElementById("article-description").innerHTML = article.description;

document.getElementById("published_date").innerHTML = (new Date(article.published_at)).toDateString();

let articleTags = document.getElementById("article-tags");
let tag;

article.tags.forEach(tg => {
if (tg.name) {
tag = document.createElement("span")
tag.classList.add("article-tag");
tag.innerHTML = tg.name;

articleTags.appendChild(tag);
}
});

const showdown = window.showdown;
const converter = new showdown.Converter();
document.getElementById("article-content").innerHTML = converter.makeHtml(article.content);

document.getElementById("article-cont").style = "display: flex; display: -webkit-box; display: -ms-flexbox;";
}

function showMissingArticleMsg(msg) {
document.getElementById("not-found").style = "display: flex; display: -webkit-box; display: -ms-flexbox;";
document.getElementById("err-msg").innerHTML = msg;
}

checkForArticle();
Error displayed on the Article page when no ID is provided
Editorial Article Page

Conclusion

In this tutorial, you installed a Strapi app and generated an article API. You then made a couple of routes of the articles API public and added sample articles to display. Lastly, you cloned a vanilla JavaScript editorial starter app and added scripts to fetch articles from the Strapi app and display them. If you’d like to add more features to the app, maybe consider including authors in the article and making the tags linkable.

--

--

Strapi is the leading open-source headless CMS. It’s 100% Javascript, fully customizable and developer-first. Unleash your content with Strapi.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store