As a developer or Technical Writer, what is the first thing you do when you run into an error or bug while coding?
You will probably Google the issue to see if someone else has faced a similar problem and solved it. If someone has found a solution to the problem they have encountered and has good writing skills, they will most likely write a blog post or an article explaining how they solved it.
As we all know, Google will only display blogs with Search Engine Optimization on the first page of search results. Unfortunately, there might be good blogs with a better solution to your problem, but you may never discover them.
For this reason, I want to show you how to create a dynamic web page with a collection of awesome blogs of your choice. In this case, you will learn how to create a collection of your favorite technical blogs over the internet based on these web development technologies.
- HTML
- CSS
- Javascript
- React
We will use React for the frontend and HarperDB as our database in this project. HarperDB is where all the dynamic data displayed on the front end will be stored.
What is HarperDB?
HarperDB is a SQL/NoSQL data management platform. In addition, HarperDB Studio, a web-based GUI where you can control and manage instances, will be used to handle data for this project.
You will then learn how to use HarperDB’s Custom Functions to create API endpoints that will help us to make an API request to a standalone API server inside HarperDB. The API request will get the dynamic blogs data stored in HarperDB, and then React will display it on the frontend.
In the end, you will learn how to create something, as shown below.
Setting up a HarperDB Account
Step 1: Start by creating your HarperDB Studio account. It's completely free to use, so sign up here: studio.harperdb.io
Creating Your First Cloud Instance
Step 2: Now select "Create New HarperDB Cloud Instance," which will be used for this project.
Step 3: Select the Instance type. We'll use the cloud instance in this case.
Step 4: Fill out the Instance details as per your preferences:
Step 5: After that, choose the specs. For the time being, we'll go with free options:
Step 6: Your first cloud instance is successfully created!
It's time to populate the cloud instance with your own data.
Creating Schema & Table data
- Open the instance tech-blogs we just established.
- We need to develop a schema for our blog list data before we can add it.
- We will name our schema collection
- Name a table as blogs and save it. This will hold all of the data from the blog records that we require.
- Each record (here, blogs) will now require a hash_Attribute. Think of hash_Attribute as a "key."
- Name the hash_Attribute: id
- In HarperDB, you can add queries (sql, nosql) as data, import a CSV, or just add a json object.
- We'll use a JSON object to store data in our app.
[
{
"title": "Overreacted",
"icon": "🔥",
"description": "Dan Abramov writes about UI engineering, software development practices, and concepts in React.js",
"tags": "react",
"blog_url": "https://overreacted.io/",
"twitter_url": "https://twitter.com/dan_abramov"
},
{
"title": "Robin Wieruch's Blog",
"icon": "☕",
"description": "Robin writes guides and tutorials about React.js, Node.js, GraphQL and JavaScript. ",
"tags": "javascript",
"blog_url": "https://www.robinwieruch.de/blog/",
"twitter_url": "https://twitter.com/rwieruch"
},
{
"title": "Dave Ceddia's Blog",
"icon": "⚛️",
"description": "Dave's articles help you learn and master frontend development with React.",
"tags": "react",
"blog_url": "https://daveceddia.com/archives/",
"twitter_url": "https://twitter.com/dceddia"
},
{
"title": "Lee Robinson's Blog",
"icon": "😄",
"description": "He writes mostly about web development and tech careers.",
"tags": "html",
"blog_url": "https://leerob.io/blog",
"twitter_url": "https://twitter.com/leeerob"
},
{
"title": "Josh W. Comeau's Blog",
"icon": "👋",
"description": "He writes articles with a focus on React, Gatsby, CSS, and animation.",
"tags": "react",
"blog_url": "https://joshwcomeau.com/",
"twitter_url": "https://twitter.com/JoshWComeau"
},
{
"title": "CSS Tricks",
"icon": "⭐",
"description": "Daily articles about CSS, HTML, JavaScript, and all things related to web design and development.",
"tags": "css",
"blog_url": "https://css-tricks.com/",
"twitter_url": "https://twitter.com/css"
},
{
"title": "Smashing Magazine",
"icon": "👊",
"description": "Articles all around CSS, JavaScript, front-end, UX and design.",
"tags": "css",
"blog_url": "https://www.smashingmagazine.com/",
"twitter_url": "https://twitter.com/smashingmag"
}
]
- Let's use HarperDB Studio to add this data to our schema.
- Go to the blogs table and select the + icon:
- It will open a blank page where you just need to paste the above JSON data as follows:
Save this data by clicking on the green button below. You will see the table like this:
Creating your first Custom Function with HarperDB Studio
What are Custom Functions?
HarperDB introduced the concept of Custom Functions in the 3.1+ release. They are customizable API endpoints that you can create and manage from within the HarperDB Studio.
- Now we have to create API endpoints to use in our app. Let's begin by making our first custom function.
- To access the functions option, go to the instance you created and select it from the navigation links:
- Click on the Enable Custom Functions button and name the project as api.
- You'll now be directed to a page where you can create routes and helper functions based on your app's requirements:
- Let's test the endpoint first.
Replace the pre-written code in the ‘examples’ API routes file with the following:
'use strict';
module.exports = async (server) => {
server.route({
url: '/',
method: 'GET',
handler: () => {
return "A blogs API";
}
});
}
The URL is set to /, which can be accessed at {custom_functions_server_url}/{project_name}.
Your custom_functions_server_url can be found on the custom functions page, simply copy it:
- Now open a new tab in your browser and test the endpoint:
- Great, it works perfectly!
Setting up API endpoints
For now, this API does not fetch any blog data. This route will help us in developing an API endpoint to retrieve this information.
Creating the API endpoint:
module.exports = async (server, { hdbCore, logger }) => {
server.route({
url: '/blogs',
method: 'GET',
handler: (request) => {
logger.debug(request);
request.body= {
operation: 'sql',
sql: 'SELECT * FROM collection.blogs'
};
return hdbCore.requestWithoutAuthentication(request);
}
});
}
As you can see, we've changed the URL to /blogs this time. The handler function will make a SQL request which will return the blog's data.
Again, this route can be accessed at {custom_functions_server_url}/{project_name}/{url_route}
We're getting the data from the blogs. Now let's make another endpoint that will display blogs according to tags:
// GET blogs by tags
module.exports = async (server, { hdbCore, logger }) => {
server.route({
url: '/blogs/:tags',
method: 'GET',
handler: (request) => {
logger.debug(request);
request.body= {
operation: 'sql',
sql: `SELECT * FROM collection.blogs WHERE tags LIKE '%${request.params.tags}%'`
};
return hdbCore.requestWithoutAuthentication(request);
}
});
}
Because we've implemented a custom handler here, you must use prevalidation methods to avoid bypassing user authentication. Read more about it here.
Testing our endpoint:
The final route file is as follows:
'use strict';
module.exports = async (server, { hdbCore, logger }) => {
// GET blogs data
server.route({
url: '/blogs',
method: 'GET',
handler: (request) => {
logger.debug(request);
request.body= {
operation: 'sql',
sql: 'SELECT * FROM collection.blogs'
};
return hdbCore.requestWithoutAuthentication(request);
}
});
// GET blogs by tags
server.route({
url: '/blogs/:tags',
method: 'GET',
handler: (request) => {
logger.debug(request);
request.body= {
operation: 'sql',
sql: `SELECT * FROM collection.blogs WHERE tags LIKE
'%${request.params.tags}%'`
};
return hdbCore.requestWithoutAuthentication(request);
}
});
}
Our API has been set up now. Let's make a project and put it into action.
Designing The Frontend
Initialize the React app using create-react-app:
npx create-react-app tech-blogs-harperdb
cd tech-blogs-harperdb
npm start
To begin, make a Header component for the Title and Description section:
import "./Header.css";
const Header = () => {
return (
<div className="header">
<h1>🔥Tech Blogs</h1>
<p>
A collection of amazing technical blogs found on web for
developers.
</p>
</div>
);
};
export default Header;
All the CSS files can be found here: tech-blogs
We've included a Footer
component as well. You can find the code here: tech-blogs-github
After that, make the card component. I'm going to call it BlogCard:
For now, all the values we're passing are hard-coded.
import React from "react";
import "./BlogCard.css";
function BlogCard({ icon, title, description, twitter_url, blog_url, tags }) {
return (
<div>
<div className="blogs-list">
<div className="container">
<div className="card">
<div className="head">
<div className="icon">
<span>🚀</span>
</div>
<div className="title">
<h2>title</h2>
</div>
</div>
<div className="tags">
<p>react</p>
</div>
<div className="description">
<p>description</p>
</div>
<div className="flex-bottom">
<div className="social-icons">
<div className="twitter">
<a href="#">
<i className="fa-brands
fa-twitter"></i>
</a>
</div>
</div>
<div className="visit-btn">
<a
href="#"
target="_blank"
rel="noreferrer"
>
<button>Visit Blog</button>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
export default BlogCard;
This was all for the front-end.
It's time to put the API endpoints we developed in HarperDB Studio to work.
Display All Blogs from API:
Step 1: Create a file Blogs/Blogs.js under components folder:
Step 2: Create a component called Blogs and initialize the states:
import React, { useState, useEffect } from "react";
const Blogs = () => {
const [isLoading, setIsLoading] = useState(true);
const [blogs, setBlogs] = useState([]);
}
export default Blogs;
Step 3: To fetch the blogs data from our API, initialize the useEffect method:
Your fetch url will be as follows:
{custom_functions_url}/{project_name}/{route_url}
useEffect(() => {
fetch("<CUSTOM_FUNCTIONS_URL>/api/blogs")
.then((response) => response.json())
.then((data) => {
setBlogs(data);
setIsLoading(false);
});
});
Step 4: Render the blog component:
return (
<div className="blogs_data">
<Header />
<div>
{isLoading ? (
<h2
style={{
display: "flex",
alignContent: "center",
justifyContent: "center",
padding: "5rem",
}}
>
Loading.. ⌛
</h2>
) : (
<div>
{blogs.map((blog) => {
return (
<BlogCard
title={blog.title}
description={blog.description}
icon={blog.icon}
twitter_url={blog.twitter_url}
blog_url={blog.blog_url}
tags={blog.tags}
/>
);
})}
</div>
)}
</div>
</div>
);
Here's what our final Blogs component will look like:
import React from "react";
import { useState, useEffect } from "react";
import "./Blogs.css";
import BlogCard from "../BlogCard/BlogCard";
const Blogs = () => {
const [isLoading, setIsLoading] = useState(true);
const [blogs, setBlogs] = useState([]);
const [tags, setTags] = useState([]);
useEffect(() => {
fetch(
`https://functions-tech-blogs-shreya.harperdbcloud.com/api/blogs/${tags}`
)
.then((res) => res.json())
.then((data) => {
setBlogs(data);
setIsLoading(false);
});
}, [tags]);
const allTags = ["HTML", "CSS", "JavaScript", "React"];
function chooseTag(tag) {
setTags(tag);
}
return (
<div>
{isLoading ? (
<h2 className="loading_el">Loading.. ⌛</h2>
) : (
<div>
<div className="nav_tags">
{allTags.map((tag) => {
return (
<div
className="tags_el"
onClick={() => chooseTag(tag)}
>
<p>{tag}</p>
</div>
);
})}
</div>
<div>
{blogs.map((blog) => {
return (
<div>
<BlogCard
key={blog.id}
title={blog.title}
description={blog.description}
icon={blog.icon}
twitter_url={blog.twitter_url}
blog_url={blog.blog_url}
tags={blog.tags}
/>
</div>
);
})}
</div>
</div>
)}
</div>
);
};
export default Blogs;
Step 5: Congratulations! You've successfully used your first API endpoint:
Step 6: Now let's use the second endpoint which returns blogs according to tags requested from the route URL /blogs/:tags
const [tags, setTags] = useState([]);
useEffect(() => {
fetch(
`https://functions-tech-blogs-shreya.harperdbcloud.com/api/blogs/${tags}`
)
.then((res) => res.json())
.then((data) => {
setBlogs(data);
setIsLoading(false);
});
}, [tags]);
const allTags = ["HTML", "CSS", "JavaScript", "React"];
function chooseTag(tag) {
setTags(tag);
}
Stage 7: We've set a dynamic routing as /${tags}. The function chooseTag will set the active tag for this route.
Updating the return method:
return (
<div>
{isLoading ? (
<h2 className="loading_el">Loading.. ⌛</h2>
) : (
<div>
<div className="nav_tags">
{allTags.map((tag) => {
return (
<div
className="tags_el"
onClick={() =>
chooseTag(tag)}
>
<p>{tag}</p>
</div>
);
})}
</div>
<div>
{blogs.map((blog) => {
return (
<div>
<BlogCard
key={blog.id}
title={blog.title}
description={blog.description}
icon={blog.icon}
twitter_url={blog.twitter_url}
blog_url={blog.blog_url}
tags={blog.tags}
/>
</div>
);
})}
</div>
</div>
)}
</div>
);
Great! We can now view blogs by selecting categories too:
That's it. You've used HarperDB Custom Functions successfully in your app.
Conclusion
Now that you have learned how to build a collection of blogs, you can take this further and use HarpedBD and React to create a blog of your own. The best way to learn from tutorials is taking what you have learned and using it to build a project of your own.
Building a project of your own will help you to take advantage of the HarperDB’s Custom Functions. HarperDB Studio is beginner friendly and their tutorials are direct to the point. Moreover, HarperDB is a better fit for projects where you need SQL and NoSQL, rapid application development, hybrid cloud, integration, edge computing and distributed computing.
Access the full code here: tech-blogs-github
Visit Tech Blogs here: tech-blogs.vercel.app
Top comments (1)
Awesome article man