I completely rewrote my personal website using Dev.to as a CMS
Tags: showdev, javascript, react, nextjs
Published: 2021-02-03 19:40:55

---
description: "I spent a weekend rebuilding my website from scratch using TypeScript, Next.js, Tailwind CSS and Dev.to as a CMS for my blog and portfolio pages."
---
The final weekend of January 2021 was uneventful in comparison with other years - in the UK we were in full lockdown due to the Coronavirus. It was, however, the perfect opportunity to completely rewrite [my personal website](https://wallis.dev).

##Why?
I decided to redesign and rewrite my website for several reasons:
* I wanted to move from JavaScript to TypeScript.
* The website was styled using [styled-jsx](https://github.com/vercel/styled-jsx), which can be a pain to maintain and IMO is a bit messy. At the moment I'm using Tailwind CSS and so far loving it and its utility-style nature; I wanted my personal website to reflect this.
* I no longer liked the design and wanted it to be cleaner and simpler.
* I wanted my blog and portfolio to be loaded dynamically from a CMS rather than having to copy+paste a new page for each entry - See the *`Originally published at wallis.dev`* at the top of this article.

<figure>
  <img src="https://dev-to-uploads.s3.amazonaws.com/i/rs1bvowr8eyxg3gly85p.png" alt="The old wallis.dev home page">
  <figcaption>My old home page</figcaption>
</figure>

##Technologies used
* **[TypeScript](https://www.typescriptlang.org)** - Since being introduced to TypeScript at work, I've started to understand the benefits over plain JavaScript.
* **[Next.js](https://nextjs.org)** - I don't try to hide the fact that I love Next.js, it's so simple to use and to date [most of my articles contain Next.js in some way](https://dev.to/jameswallis).
* **[Tailwind CSS](https://tailwindcss.com)** - Lately I've been using Tailwind CSS heavily. To quote their homepage, it enables me to "rapidly build modern websites without ever leaving [my React component]". Tailwind CSS also made it incredibly easy to add a [dark mode](https://tailwindcss.com/docs/dark-mode). Also [Tailwind Typography](https://github.com/tailwindlabs/tailwindcss-typography).
* **[Dev.to API](https://docs.dev.to/api)** to dynamically build the blog and portfolio pages ⬅️  *My favourite feature*.

##Using Dev.to as a CMS
My favourite part of my website is the use of Dev.to as a Content Management System for the blog and portfolio pages. I've seen the Dev.to API utilised before to display a user's articles on their website but, AFAIK, not quite in the same way as I've applied it.

The benefits of using Dev.to as a CMS are:
1. Dev.to stores the articles and any images that are uploaded and used.
1. I can use Dev.to's editor and the ability to draft an article and publish it later.
1. Has a built-in RSS feed that I can use to share my articles to other sites such as [CodeNewbie](https://community.codenewbie.org/) and Medium.
1. Although Dev.to has the article first, the use of a canonical URL ensures that Google and other sites see my personal website as the source site for the articles.
1. ~~Converts the article into HTML for me.~~ *I ended up rendering the HTML from the article markdown myself, as it required fewer requests to the Dev.to API.*

###Disclaimer
Before I continue I want to *stress* that I intend to use Dev.to purely for my blog and portfolio (past projects / `showdev`). **I won't be using Dev.to to create pages which are not articles** and would cause Dev.to to become cluttered with spam if others follow suit. For example, the about section on the home page is hardcoded into the website and if I created a page for my education history, I'd keep that purely for the website and wouldn't post it to Dev.to - [I'd probably use Markdown for these](https://dev.to/jameswallis/combining-markdown-and-dynamic-routes-to-make-a-more-maintainable-next-js-website-3ogl).

###How it works
[View the code on GitHub](https://github.com/james-wallis/wallis.dev)

Built using Next.js, the website uses two dynamic routing functions ([`getStaticPaths`](https://nextjs.org/docs/basic-features/data-fetching#getstaticpaths-static-generation) and [`getStaticProps`](https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation)) to generate the [blog](https://github.com/james-wallis/wallis.dev/blob/master/pages/blog/%5Bslug%5D.tsx) and [portfolio](https://github.com/james-wallis/wallis.dev/blob/master/pages/portfolio/%5Bslug%5D.tsx) pages.

Before an article is displayed on my website, it must meet the two following requirements:
1. Must be published (obviously)
1. Must have a canonical URL directing to my website. This enables me to pick which articles are displayed, what the article's path will be on my website (not the post ID). Moreover, an article with a canonical URL pointing to `https://wallis.dev/blog/...` will be built as part of my blog whereas, if its canonical URL is `https://wallis.dev/portfolio/...` it will be a portfolio piece.

For every article that meets the requirements, the subsequent build process is followed:
1. At build time, Next.js calls the `getStaticPaths` function which 
    1. Fetches a list of my published articles using the Dev.to API ([`/api/articles/me`](https://docs.dev.to/api/#operation/getUserArticles)).
    1. Converts the article's markdown to HTML.
    1. Saves the articles to a cache file for use in the next step. 
    1. A dynamic page is created within the Next.js context for each article - the page `slug` will be the canonical URL path.

1. For each page, Next.js calls `getStaticProps` which fetches the page's article from the cache. The article contains the name, description and HTML. 
    * *I also attempted making another API request to the Dev.to API ([`/api/articles/{id}`](https://docs.dev.to/api/#operation/getArticleById)) to fetch the page's article, so I could use the HTML rendered by Dev.to. However, this caused build failures as I was making too many API requests at once - so now I render the markdown using [`remark-html`](https://github.com/remarkjs/remark-html).*
1. Finally, the page is rendered. I use custom elements to display the article `name` and `description` and then display the HTML I [rendered earlier in `getStaticPaths` using `remark-html`](https://github.com/james-wallis/wallis.dev/blob/master/lib/markdown.ts#L19-L29). For styling, I use the [Tailwind Typography plugin](https://github.com/tailwindlabs/tailwindcss-typography).

To ensure that the website is always in sync with my articles on Dev.to, I use a [Vercel Deploy hook](https://vercel.com/docs/more/deploy-hooks) which is triggered each time I create or update an article using a [Dev.to webhook](https://docs.dev.to/api/#tag/webhooks). I use a Deploy Hook rather than [Incremental Static Regeneration](https://nextjs.org/blog/next-9-5#stable-incremental-static-regeneration) so that the blog is only rebuilt when something has changed rather than at random intervals.

*Note: I use Dev.to APIs that require authorisation as they seem to have a higher request limit compared to the public routes. When using public APIs and fetching each article via the article API, I found that my builds were failing with a `429` error which is Dev.to rate-limiting requests. - I probably could switch to using public APIs now that I'm using a cache to read the articles from.*

**I'm currently writing a detailed article which describes in greater detail how my website utilises Dev.to as a CMS, stay tuned (and follow on Dev.to to be notified when I release it)!**


###How it looks
[Visit wallis.dev](https://wallis.dev)

<figure>
  <img src="https://dev-to-uploads.s3.amazonaws.com/i/7apbs7bdr6o1fwiouwc5.gif" alt="Navigating through my website">
  <figcaption>Navigating through wallis.dev</figcaption>
</figure>

###Future improvements
1. ~~Add syntax highlighting to code blocks like on Dev.to.~~ [Completed using `highlight.js` and `remark-highlight.js`](https://github.com/james-wallis/wallis.dev/blob/master/lib/markdown.ts#L24).
1. Add a [contact form using EmailJS](https://dev.to/jameswallis/using-emailjs-with-captcha-verification-in-a-next-js-application-1g1g).
1. Only rebuild the website if the content of an article has changed or one is created - reduces the website being needlessly redeployed.

##Summary
In this article, I discussed rewriting my personal website from the ground up using Dev.to as a Content Management System for the blog and portfolio pages.

Like the idea of using Dev.to as a CMS for your blog? React! Found something I could improve or that you would have done differently? Let me know in the comments.

> Looking to use the Dev.to API to power your website or blog? [Read my how-to post.](https://dev.to/jameswallis/adding-a-blog-with-a-dev-to-backend-to-a-static-next-js-website-with-canonical-urls-1i9g)

Thanks for reading!

**[By the way, you can view this article live on my website here.](https://wallis.dev/blog/rewriting-my-website-with-a-devto-cms)**