Brandon Travis

Stock photo of computer

How I built this blog

Last updated on: Wednesday, December 29, 2021

I decided to use the following technologies to build this blog, Contentful for the CMS, Next.js for the frontend, and Commento for the commenting system to which I self-host.

The frontend is currently deployed on Vercel since it was one of the easiest ways to deploy a Next.js project and it's also free and you can never beat free. Also with Vercel's integration with Next.js, I use ISR or incremental static regeneration which allows me to publish new blog posts without having to rebuild the page every time I need to publish something new and also grants me the main benefits of serving static files over server-side rendering everything. Though there are some cons with this as with all methods, I will have to wait the specified time after a person visits the page to have the page rebuild itself to which I have it set at 30 seconds after a visit. While I would prefer to have the page reflect the changes immediately, I am okay with having this downside compared to using the other methods that Next.js gives me.

return { props: { post, params, related }, revalidate: 30, // In seconds }

The UI library that I use for the frontend is unsurprisingly Material-UI v5 which is probably one of, if not, the most common UI frameworks that are used on the web. It was interesting and in the future, If I were to dedicate more time for this side-project, I definitely would use Tailwind, while I can still implement tailwind, most of the heavy-lifting is done already with Material-UI and only minor tweaks with CSS were needed which is easily handled with inline-css. The metadata for this is website is handled using an npm package called Next-Seo.

<NextSeo title={post.items[0].fields.title} description={post.items[0].fields.summary} canonical={`https://blog.brandon-travis.com/post/${post.items[0].fields.slug}`} openGraph={{ url: `https://blog.brandon-travis.com/post/${post.items[0].fields.slug}`, title: post.items[0].fields.title, description: post.items[0].fields.summary, type: 'article', article: { publishedTime: post.items[0].sys.createdAt, modifiedTime: post.items[0].sys.updatedAt, tags: post.items[0].fields.tags, }, images: [ { url: 'https:'+post.items[0].fields.preview.fields.file.url, width: 800, height: 600, alt: post.items[0].fields.preview.fields.description, type: post.items[0].fields.preview.fields.file.contentType, }, ] }} />

Now with this, I may or may not be missing several needed tags that are used for SEO, but I will figure it out eventually. I also just learned while building this site, that JSON-LD is also a thing now, which now tells me, I am very behind on the times and that I need to get up to speed again, sadly.

To render the Markdown on the page I use an npm module called ReactMarkdown, with several remark and rehype extensions to expand the capabilities of ReactMarkdown. To achieve syntax highlighting, I use a package called React Syntax Highlighter, and for the styling for this, I use one of the integrated stylings with this package called materialDark. The main reason that I choose to use markdown compared to simpler solutions like a wysiwyg (what you see is what you get) editor is due to the ease it is to implement additional features compared to wysiwyg editors which require more work at least in my opinion.

My current ReactMarkdown configuration looks like this

<ReactMarkdown children={post.items[0].fields.post} remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]} components={{ img: ({ node, children }) => { return ( <Box sx={{ display: 'flex', justifyContent: 'center'}}> <Shimmer src={node.properties.src} alt={node.properties.alt} w={node.properties.w || 300} h={node.properties.h || 300} quality={node.properties.quality} /> </Box> ); }, p: ({ node, children }) => { return ( <Box component={"div"}> <Typography sx={{ lineHeight: 2, fontSize: '115%' }} mt={5} variant={"body1"}> {children.map((item) => ( item ))} </Typography> </Box> ); }, code({node, inline, className, children, ...props}) { const match = /language-(\w+)/.exec(className || '') return !inline && match ? ( <SyntaxHighlighter children={String(children).replace(/\n$/, '')} style={materialDark} language={match[1]} PreTag="div" {...props} /> ) : ( <code className={className} {...props}> {children} </code> ) } }} />

A benefit that comes from using contentful along with markdown is that I get the benefits of markdown along with a fully built CMS that I do not have to manage at all. Less work for me is always better than having to not be lazy. I get to avoid having to dynamically update markdown metadata and because of that I get to avoid using extensions like Frontmatter, that other people may be using if they deploy to Vercel without the use of a CMS, since Vercel builds the required files each time a new push is committed and due to this, using createdAt or updatedAt will no longer work.

Now, I ain't much of a creative person as you can probably tell, so, for starters, the idea for this design came directly from Microsoft Stories, with maybe a few variations here and there to fit within the scope of this little project and the maybe five to 10 blog posts I will write before forgetting this thing even exist 🙂. Now hopefully people won't find this design disgustingly bad, maybe just a little bad but you know, I made it so it's like my little child. Maybe in the future, the design of this little blog of mine will change, and that I'll make sure it is in dark mode because we all love dark mode, but for now I'm a bit lazy.

Now if you unlikely stumble upon this website of mine before the homepage is fully decorated with various posts, you may be thinking to yourself, there is a bunch of empty space here, why? This is due to the design I have derived my inspiration from which I have listed earlier. As the pages get more and more content, the design of the homepage will finally come alive, hopefully, sooner than later. But knowing me, it will probably be later.

There are several things that I would love to add later, two of which are a like counter for posts and a subscription for when new posts are added. If these features will ever be added no one knows but one day maybe, they will be added.

If you made it this far, you must of either thought this was very interesting or you might have just been bored, but thank you either way for reading.


Related Posts

Picture of a stylized brain holding up weights
My experience with a coding bootcamp
picture of javascript framework, VueJs
VueJS
Picture of Javascript framework, Reactjs
ReactJs, NextJs, and PreactJS
a clock that shows the time passing
Why I started coding
Picture of a man writing on a piece of paper and also using a laptop
My experience with working

Copyright © Brandon-travis.com 2022.