Why Am I Starting A Blog? (And the Process Behind It)
Hello World!👋 I'm Jorge Pasco. Welcome to my first blog post and thanks a lot for being here. I won't clutter this with personal information, since I've already done that somewhere else (never forget the DRY principle). Quick introduction, moving now to the point👌.
So, why?
There's not a unique reason behind this journey I'm hoping into. Let's start with the obvious one. It's no secret that many experienced engineers – and professionals from different backgrounds – recommend starting a blog as a companion to your learning path. But maintaining a blog is no easy task; to write an attractive and meaningful article, an author must go through – among other related diligences – searching for an ideal topic, iterating over the writing process, and specially dedicating time to do an extensive research. And you may be asking: Isn't that the point? Well, exactly. In order to communicate useful knowledge to the world, one should make sure to understand profoundly enough what they will be writing about.
By putting effort into this blog I will reinforce my knowledge in software engineering while I potentially make other developer's life a bit easier, which constitutes my second big motivation. In my eyes, one of the greatest virtues of the software development community is how enthusiastic people is about sharing knowledge. I'm self taught and, if it wasn't for the amazing developers that shared their knowledge expecting nothing in return, I'm not sure I'd be working in this industry right now. This is my way of contributing my grain of sand to the community.
Now, in my case, it goes even beyond that. Something that not many people know is that I actually enjoy writing (much more than how I excel at it). I would say that my two big passions are software development and cinema; and I spent a good amount of time writing about the latter in Letterboxd (a social network for film enthusiasts). But I've postponed my plans on doing the same for the former due to the feeling of not being proficient enough. Being honest, I still have that feeling. However, I figured there will never be a perfect time and, by taking the step of starting, I am encouraging myself into a virtuous circle.
I'm self taught and, if it wasn't for the amazing developers that shared their knowledge expecting nothing in return, I'm not sure I'd be working in this industry right now. This is my way of contributing my grain of sand to the community.
The Development Process
Now, let's move to the juicy part of the post🧃. How did I build this site? As almost every software development project, it was an iterative process. But I decided to determine the technologies to use beforehand, in order to avoid over-complicating a process that should be pretty straightforward. Meet the technologies this blog is built upon:
NextJS(with Typescript) as the web development framework.
Semantic-ui for components.
Sass to write custom styles.
Contentful to manage the content.
The blog is part of a bigger project, my personal site, where I used some additional technologies (and made a few bad decisions). If you're interested, you can find the full source code on Github.
NextJS
React has always been my technology of choice for building User Interfaces. However, traditional React applications rely purely on Client Side Rendering (CSR), which means that the server send a blank html file and big chunks of javascript code that will take care of rendering all of the visual elements once they arrive to the client. Two big problems emerge from this approach:
The First Contentful Paint could take a lot of time, especially as the size of the application increases. What this means, is that after the client (i.e. web browsers) make a request to the server, there will be a small period where the site will show empty, since the JavaScript code is still loading. This can become a UX problem very quickly. The following image, taken from this article, illustrates this very well.
SEO for the page is affected: Search Engines can crawl and index content from server side rendered sites immediately. The HTML for CSR sites can take days or weeks to be indexed by the engines, and there's even the risk of certain parts of the site not being indexed at all. Here's an introductory article if you want to extend on this.
Now, Server Side Rendering also has disadvantages, mainly related to the fact that every request to the server triggers a new HTML render (and all of the previous logic process, which often includes data-fetching). This could be required if, for example, the site needs to provide data that is exclusive to each user. But in the case of a blog, the data for everyone is the same.
This is where Static Site Generation comes into play. With this approach, the required data is fetched at build time. Meaning that the logic and data-filling process will only run when the application is built and, once deployed, the same files will be served for each request, increasing the speed of the response, hence making the site blazing fast.
Next is a React Framework that allows you to do server-side rendering and Static Site Generation of React code. It also takes care of different optimization processes such as code splitting and route pre-fetching. This is why I decided to pick it as the development framework for this project.
The option of using a traditional SSG tool like Gatsby or Hugo was also considered, but that would imply getting used to the different development process, such as the plugin-based development for Gatsby; whereas developing in Next is almost as traditional React, with a few difference in the folder structure and a couple of data-fetching functions. Besides, Next offers Incremental Static Site Regeneration, which means that the site will re-build after a specified period (but only if a request is made); this will be extremely helpful, since I will not need to manually re-build the site after every new post.
Semantic-UI and Sass
The decision for these two doesn't have much science behind it. I have yet to find a UI Components/Styles Framework that feels perfect to me, so I've tried a few of them (Material UI, Bootstrap, Bulma) and decided to go for Semantic-UI this time. I gotta say I liked working with it. It's super simple to pickup and customize, and it offers a wide catalogue of useful components (a couple of them that didn't quite fill my expectations, but it is what it is). Sass is my preferred CSS preprocessor to improve organization and legibility of my styles.
Contentful
The missing part of the stack would be the one responsible of taking care of the most important part of the blog: t̶h̶e̶ ̶a̶n̶i̶m̶a̶t̶i̶o̶n̶s̶ the content. I am fan of the power/simplicity of Markdown, so initially I considered the option of using MDX with something like Theme-UI. Mdx allows you to insert React Components into a Markdown file (imagine my hype), and Theme-UI provides "themeable" design systems to make them look good. This said, I definitely didn't want to add a new file to the project every time I needed a blog entry, so I had to go with a Content Management System (CMS).
If you know of WordPress, you might be familiar with the term "CMS". These kind of systems have dominated the web for their power and ease of use. But they have never shone for their flexibility, since it ties the developer to their delivery system, which often falls short if you need (or want) detailed customization and scalability. This is why Headless CMS are a terrific alternative that decouples the system that handle the content (i.e. the blogs posts in this case), from the delivery system (the website). Here's an insightful article on the topic.
I found the API-based approach of Contentful really comfortable to work with, and the Model system powerful enough for what I had to work with. (More on this below).
Building Steps
While you might fully understand the process by just following this text, I recommend to go through it while looking at the source code on Github.
There's no blog without content, so the first step was to build the Model for a blog post. A model in Contentful is the equivalent of an Entity in programming terms. It represents a type of the content you want to create. A Model has fields, which hold the specific information for each item of the model. I modeled my Blog Post as follows:
As you see, nothing fancy, just enough for what we need. Notice the slug field, it will be used to defined the route of the post on the site. We have different field types. Notice that we use the Rich Text type for the post content, since we want to be able to use formatting, add images, etc.
The next step is creating our Next application and getting the data into it. Bootstrapping a Next Application is super simple, as vercel provides a npm script similar to create-react-app
, called – you guessed it – create-next-app
. So you can create a basic Next Application with the command npx create-next-app <name_of_project>
.
Let's do a quick overview of how the folder structure determines the routes in a NextJS application.
Inside the pages folder, each React file (.js, jsx, ts, tsx) will be a route. Vercel calls this a file-system based router. NextJS will automatically route files named index
 to the root of the directory. So pages/index.tsx
becomes the route /
and pages/blog/index.tsx
becomes the nested route /blog/
. What is that [slug].tsx
file? We will find out soon.
We will also need to install a few of packages related to Contentful. Those would be "contentful", "@contentful/rich-text-react-renderer" and "@contentful/rich-text-types". You can use npm install
for that.
Fetching data from Contentful is really easy. We create a client and request what we need through it. I created two utility functions: one to fetch all Posts entries, and the other one to fetch a single one. You will see it in action soon. Here's the full implementation:
Note that you have to indicate the space id, accessToken and the content type (in this case blogPost).
Let's continue by exploring the blog/index
file. It provides the home page for our blog. Here we will introduce the concept of getStaticProps
. Quoting NextJS documentation:
If you export anÂ
async
 function calledÂgetStaticProps
 from a page, Next.js will pre-render this page at build time using the props returned byÂgetStaticProps
.
This means, that this function will take care of fetching the required data and passing it to the component as a prop to render it. Here will lie our first integration with Contentful.
We can see that in the getStaticProps
function, we are fetching the posts from Contentful (in fetchPosts()
) and through the returning object, we are passing the posts as a prop to the component.
We can now create Custom Component to Render the information in the way we want to.
We simply take the information from a post object and transform it into a JSX component (Card is a custom component I reuse in different parts of the application). Note that we give the Card a link in the form of `/blog/posts/${slug}`
. As I mentioned before, we will have a route for each post, determined by its slug. Now in the main component, we can iterate over the posts
array that getStaticProps provided to our Component. Each Card will redirect to the post url.
That would be the meaty part for the Index, we now have a preview for our posts that we can customize as we like. As the blog grows, we might want to implement something as pagination, but for now this is more than enough.
Now let's move to the magic. The [slug].tsx
file. We will also use getStaticProps
here, but also a new function that will let us generate a route for every post: getStaticPaths
. Quoting Next Documentation:
If a page has dynamic routes and usesÂ
getStaticProps
 it needs to define a list of paths that have to be rendered to HTML at build time.If you export anÂ
async
 function calledÂgetStaticPaths
 from a page that uses dynamic routes, Next.js will statically pre-render all the paths specified byÂgetStaticPaths
.
What is a dynamic route? It's a route that will not have a predefined name, but rather creates it dynamically from data you specify. To define a dynamic route we have to wrap the parameter of it with "[]" in the file name. So, in our case we have a dynamic route with a slug
parameter. Now, how do we tell Next what this slug is gonna replaced with? Indeed , with the getStaticPaths
function.
As you see, we use our fetchPosts
function and create an array of objects. These objects will indicate what's going to replace each param in our dynamic route. In this case we will replace the slug
param with the slug for each one of our posts from Contentful. The fallback param indicates wether or not we want Next to try to generate the path with the requested name or just return a 404.
For example, if a user tries to go to a route called: /blog/posts/<currently-unexisting-post-slug>
it will return a 404 if fallback is false, whereas it will try to build the requested path and temporarily render a specified component while it does so if fallback is true. It's not an easy concept to grasp, but after a bit of playing you will get your head around it. The most important thing to know is that if you specify fallback to be true you must give the component a fallback component when the Next Router Object is of type fallback (We'll see this soon), otherwise an error will occur on build time.
The getStaticProps
function for this component is a bit different:
As you see, now it receives a params
prop, which comes from the getStaticPath
function, with this, we can fetch the specific data for the correspondent post of the route, using our fetchSinglePost
function. And what's that revalidate parameter? 🤔. Remember the concept of Incremental Static Site Regeneration? This is where we specify if we want to have it, and how often (in seconds) we want to revalidate the content to trigger a re-build. In this case we specify 2 hours(60 seconds * 60 minutes * 2 hours), which should be enough for the frequency I will be posting.
Now, since we receive the post as the parameter to our component, we can render the information how we like 🤩. Although, working manually to render each of a Rich Text field could be too cumbersome. That's why we installed the rich-text-react-renderer
and rich-text-types
packages. We need to import the following:
With that we can transform our Rich Text nodes into HTML tags:
By default, the documentToReactComponents
function doesn't render embedded assets, so we have to specify how do we want to render those type of nodes. In this case we created the <PostImage/>
component to handle that:
I recommend using the Image component, which you can import from 'next/image'
, as it handles Image optimization for you, and wrapping it in a div for further customization.
One last thing, since we used fallback: true
in our getStaticPaths
function, we need to specify the Fallback component to load while it tries to generate the new path. Let's import useRouter
from 'next/dist/client/router'
and add this to the start of our component.
And that's it! 🎉 We just have to start creating our BlogPosts from Contentful and they will be automatically fetched and displayed in our application.
That's it for now, folks. Thanks for reading through, and I hope you learn something valuable and enjoyed the reading. Feel free to share, see you next time! 🙌