First of all, welcome!
If you follow me on Twitter, then you'll know that I've recently been re-writing Ionic React Hub! There wasn't anything wrong with how it was working before hand, but I wanted to make it more of a platform/hub rather than just a page containing the UI Examples!
Now what you'll find here is the UI Examples as you know them. I didn't want to change this part too much as I quite liked the simplicity. However, a few changes in that, they now have their own dedicated page which you can find at /ui-examples
. Also on the homepage you'll see a few of the latest ones, as well as under a single post view. Pretty neat, right?
Tech Stack
NextJS / React
On to the fun stuff now after a short intro... The tech stack! What did I use to build this site? Well, I love modern web tech! I always have! The main tech stack here is NextJS
for the front-end and utilising the awesome api routes to hook into some back-endy node
code when needed! Each page is built statically with incremental re-generation, which is all built into Next, if you're familiar with it, then this will make total sense!
StrapiJS
For the actual UI Examples that I post on here, they are actually being fetched from a DB. Keeping with the fun, fresh modern web tech - I went with StrapiJS
. This is a headless CMS which is spun up and served on my personal Digtial Ocean server and connected to a PostgreSQL
database. I could have used MongoDB for this, but I had it already set up to use PSQL from the first site, so, no point re-inventing the wheel really. Using NextJS, I can easily build dynamic pages for each post using the [slug].js
file name in conjunction with getStaticProps/getStaticPaths. With the incremental builds, it means that when I add a new record to my DB with my new UI Example, then a new corresponding page will be statically generated.
export async function getStaticProps() {
const response = await fetch(`${ process.env.API_URL }/posts`);
var data = await response.json();
data = parseImages(data);
return { props: { posts }, revalidate: 1 }
}
TailwindCSS
For the styling across the whole site I've used TailwindCSS. This is a utility first CSS framework that allows us as developers to style our content using class names only. Now, I'm a huge fan of custom CSS and SASS modules, as you know or will know from my UI Examples, however Tailwind is just way too easy to use, especially with React/NextJS!
<h1 className="tracking-tighter font-bold text-2xl text-white bg-blue-500 p-2 m-2">Hello World!</h1>
Blog (Custom)
I didn't want to just do the standard thing and implement a blogging plugin or use a third party platform. Nowadays, with the tools and web tech readily available to us, it's very easy to build these ourselves. For the blog section, I have went with simple Markdown with some plugins to style and look after the formatting; Prism, Remark, Gray Matter and Markdown. All I have to do is write a blog post inside a .md
file and save it inside my posts folder and my setup will take care of the rest! It results in this very page you're reading now.
Here's some context around the plugins which is actually lifted from NextJS' blog itself, but it explains it exactly how I would;
Prism is a popular syntax highlighter commonly used with Markdown. This example shows how to use Prism with NextJS.
With NextJS you can write server-side code directly inside some special functions. For example, you can read Markdown files from the filesystem (fs
) – including parsing front matter with gray-matter. For example, let's assume you have a Markdown file located at posts/my-post.md
.
We can retrieve that file's contents using getPostBySlug('my-post')
.
import fs from 'fs';
import { join } from 'path';
import matter from 'gray-matter';
export function getPostBySlug(slug) {
const realSlug = slug.replace(/\.md$/, '');
const fullPath = join(docsDirectory, `${realSlug}.md`);
const fileContents = fs.readFileSync(fullPath, 'utf8');
const { data, content } = matter(fileContents);
const time = readTime(content);
data.readTime = time;
return { slug: realSlug, meta: data, content };
}
Then, we can transform the raw Markdown into HTML using remark plugins.
import remark from 'remark';
import html from 'remark-html';
import prism from 'remark-prism';
export default async function markdownToHtml(markdown) {
const result = await remark().use(html).use(prism).process(markdown);
return result.toString();
}
Passing the content
returned by getPostBySlug('my-post')
into markdownToHtml(content)
would convert a Markdown file like this:
---
title: 'My First Post'
description: 'My very first blog post'
---
# My First Post
I **love** using [Next.js](https://nextjs.org/)
```js
const doc = getDocBySlug(params.slug);
```
into this HTML, which includes the proper elements and class names.
<h1>My First Post</h1>
<p>I <strong>love</strong> using <a href="https://nextjs.org/">Next.js</a></p>
<div class="remark-highlight">
<pre class="language-js">
<code>
<span class="token keyword">const</span> doc <span class="token operator">=</span> <span class="token function">getDocBySlug</span><span class="token punctuation">(</span>params<span class="token punctuation">.</span><span class="token property-access">slug</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code>
</pre>
</div>
I've also created my own function to work out an estimated read time
for each post. This is a simple calculation based on some average reading speeds and word counts.
Other note-worthy things
I've included some other cool things as part of this site as well. You'll see the share button to Twitter and the copy link at the end of this post, which again is a custom function to just open a window with the correct URL to share to Twitter.
For all of the Social Meta data like social sharing images, and titles/descriptions etc, I've utilised NextJS' Head
tag and created a custom component which dynamically gets fed data for each page meaning I don't need to do anything!
If you sign up to my mailing list, you'll see some magic happen as well, which is a plugin called react-......
- I'm not gonna tell you! That would ruin the surprise!!
There's some other things, but I've covered pretty much the main core bits of tech used!
Thank you
Well hopefully you enjoyed this first blog post as part of Ionic React Hub
! Future posts will include tutorials specific to Ionic and React for building slick mobile apps, mobile app development, CapacitorJS and more! Be sure to sign up to be notified of new content using your email - I'll also be sending out early access to all new premium content in the future to email subscribers!