Crafting Innovation
This blog is about my experience taking part in the Hashnode APIs Hackathon 2024.
This hackathon has provided me with an opportunity to explore and experiment with the potential of Hashnode's new API by creating new starter theme templates.
I was also grateful for Favourite Jome introducing me to the 'hashnode client' package by CreoWis; it is an npm package with several react hooks to connect to Headless Hashnode and work with your blog data to create a custom blog front-end user interface.
For this hackathon, I decided to take part in Category 2: Create a new starter-kit theme. Over the days, I created and submitted PR for three new starter-kit themes.
Of the three starter-kit themes I created, two are made using the pages directory (minimalistic and timeline), and the third, 'magazine', is made using the app directory and hashnode client.
All three themes have been made using next.js and shadcn/ui. I have also made use of a lot of the same components for the application.
In all three themes, I have used next.js with typescript and shadcn/ui as the UI library, along with lucid icons for icons. I have tried to make all the themes responsive using tailwind css too.
Hashnode Public API
The Hashnode Public API, which is based on GraphQL, provides an interface for interaction with Hashnode. This essentially means that Hashnode can function as a blog Content Management System (CMS), allowing for the integration of data as per individual requirements.
As someone who does not have much experience with GraphQL, the gql playground that Hashnode provides has been of great help. It facilitates a better understanding and effective utilization of the API.
Adding shadcn/ui
pnpm dlx shadcn-ui@latest init
Then I chose the following options:
Would you like to use TypeScript (recommended)? yes Which style would you like to use? › Default Which color would you like to use as base color? › Zinc Where is your global CSS file? › › styles/index.css Do you want to use CSS variables for colors? › yes Where is your tailwind.config.js located? › tailwind.config.js Configure the import alias for components: › components Configure the import alias for utils: › lib/utils Are you using React Server Components? › yes
Then I used the following command to install individual components:
pnpm dlx shadcn-ui@latest add <component name>
Initially, after installing a component, I did get an error I did the following to solve it:
import { cn } from "@/lib/utils" I changed it to the following import { cn } from "../../lib/utils"
Once the components were working I added light/dark mode with the help of
next-themes
.
Adding custom font
To make life easier for me and for anyone who might use this template, I did add two of my favorite fonts from font share. The fonts I added are Satoshi and Ranade. They can be used for free for personal use, and I have verified that information by messaging them.
To add those fonts, I followed the following steps:
I downloaded the font family from their site.
I created a new folder called fonts inside the assets folder.
I copied and pasted the files with woff2, ttf, woff and eot extension.
Then I went to the tailwind.config.ts file and added the following part:
fontFamily: {
satoshiMedium: 'Satoshi-Medium',
satoshiBold: 'Satoshi-Bold',
satoshiBlack: 'Satoshi-Black',
ranadeLight: 'Ranade-Light',
ranadeLightItalic: 'Ranade-LightItalic',
ranadeRegular: 'Ranade-Regular',
ranadeItalic: 'Ranade-Italic',
ranadeMedium: 'Ranade-Medium',
},
- Then I went to styles/index.css and added the following code:
@font-face {
font-family: 'Satoshi-Medium';
src:
url('../assets/fonts/Satoshi-Medium.woff2') format('woff2'),
url('../assets/fonts/Satoshi-Medium.woff') format('woff'),
url('../assets/fonts/Satoshi-Medium.ttf') format('truetype');
font-weight: 500;
font-display: swap;
font-style: normal;
}
@font-face {
font-family: 'Satoshi-Bold';
src:
url('../assets/fonts/Satoshi-Bold.woff2') format('woff2'),
url('../assets/fonts/Satoshi-Bold.woff') format('woff'),
url('../assets/fonts/Satoshi-Bold.ttf') format('truetype');
font-weight: 700;
font-display: swap;
font-style: normal;
}
@font-face {
font-family: 'Satoshi-Black';
src:
url('../assets/fonts/Satoshi-Black.woff2') format('woff2'),
url('../assets/fonts/Satoshi-Black.woff') format('woff'),
url('../assets/fonts/Satoshi-Black.ttf') format('truetype');
font-weight: 900;
font-display: swap;
font-style: normal;
}
@font-face {
font-family: 'Ranade-Light';
src:
url('../assets/fonts/Ranade-Light.woff2') format('woff2'),
url('../assets/fonts/Ranade-Light.woff') format('woff'),
url('../assets/fonts/Ranade-Light.ttf') format('truetype');
font-weight: 300;
font-display: swap;
font-style: normal;
}
@font-face {
font-family: 'Ranade-LightItalic';
src:
url('../assets/fonts/Ranade-LightItalic.woff2') format('woff2'),
url('../assets/fonts/Ranade-LightItalic.woff') format('woff'),
url('../assets/fonts/Ranade-LightItalic.ttf') format('truetype');
font-weight: 300;
font-display: swap;
font-style: italic;
}
@font-face {
font-family: 'Ranade-Regular';
src:
url('../assets/fonts/Ranade-Regular.woff2') format('woff2'),
url('../assets/fonts/Ranade-Regular.woff') format('woff'),
url('../assets/fonts/Ranade-Regular.ttf') format('truetype');
font-weight: 400;
font-display: swap;
font-style: normal;
}
@font-face {
font-family: 'Ranade-Italic';
src:
url('../assets/fonts/Ranade-Italic.woff2') format('woff2'),
url('../assets/fonts/Ranade-Italic.woff') format('woff'),
url('../assets/fonts/Ranade-Italic.ttf') format('truetype');
font-weight: 400;
font-display: swap;
font-style: italic;
}
@font-face {
font-family: 'Ranade-Medium';
src:
url('../assets/fonts/Ranade-Medium.woff2') format('woff2'),
url('../assets/fonts/Ranade-Medium.woff') format('woff'),
url('../assets/fonts/Ranade-Medium.ttf') format('truetype');
font-weight: 500;
font-display: swap;
font-style: normal;
}
That's it. Now those custom fonts can be used in the application with Tailwind.
In most of the themes, a custom font has been used.
Minimalistic Theme
I created this theme using the enterprise template as a reference and implemented the use of shadcn/ui.
PR: https://github.com/Hashnode/starter-kit/pull/82
Video (running locally)
Previously, I worked on this starter kit theme for my submission to the Headless contest, and I explained how I did it in this blog post. However, I was not done since I was left with some incomplete tasks.
One of the biggest problems I faced at that time was not being able to render images that were embedded inside the post. After going through the documentation and having a better understanding, I am now proud to say that I successfully solved that issue with this submission.
Previously:
Now:
Reason: So the reason is that I was trying to render the content as markdown, but when I tried to display it by using a dangerouslySetInnerHTML
property and inserting raw HTML directly into an element, it worked.
Timeline Theme
This theme has been inspired by Tailwind CSS's blog.
PR: https://github.com/Hashnode/starter-kit/pull/86
Video (running locally)
Home screen on dark mode
Search Sheet
As I am using next.js with shadcn/ui a lot of the same components have been used in all three of my submitted themes.
Bento Theme
This theme has been created with the next.js app directory. This theme also uses the 'hashnode client' package to fetch posts and comments. Since that package is still WIP, I have used the hooks that are currently available.
PR: https://github.com/Hashnode/starter-kit/pull/85
Video (running locally)
Home screen
Card when hovered over
Conclusion
Taking part in this hackathon has been a very rewarding experience for me since I have learned a lot about the usage of Hashnode's API and the potential it holds.
This hackathon has also made me go out of my comfort zone and enhanced my knowledge about GraphQL for which I am very grateful. I hope someone else finds some value in the themes I created.
PS: I have endeavored to ensure that all themes are responsive and that all mentioned functionalities operate seamlessly. However, there may be aspects that I have overlooked. If you encounter any bugs or have suggestions for improvement, I welcome your feedback via the comments section.