<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Perry Raskin</title>
    <description>The latest articles on DEV Community by Perry Raskin (@perryraskin).</description>
    <link>https://dev.to/perryraskin</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F56059%2F85a1359e-1bb9-499e-b994-2744c89c5588.jpeg</url>
      <title>DEV Community: Perry Raskin</title>
      <link>https://dev.to/perryraskin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/perryraskin"/>
    <language>en</language>
    <item>
      <title>Quick Start: Next.js and Plaid to pull financial data</title>
      <dc:creator>Perry Raskin</dc:creator>
      <pubDate>Sun, 15 Mar 2020 23:22:38 +0000</pubDate>
      <link>https://dev.to/perryraskin/quick-start-next-js-and-plaid-to-pull-financial-data-37h</link>
      <guid>https://dev.to/perryraskin/quick-start-next-js-and-plaid-to-pull-financial-data-37h</guid>
      <description>&lt;p&gt;Now that I've got a lovely &lt;a href="https://raskin.me" rel="noopener noreferrer"&gt;Next.js personal website&lt;/a&gt; up and running, I'm ready for my next project. I've always enjoyed grabbing CSV files from my credit card or bank accounts and playing around with the financial data. It allowed me to run super custom reports for properly managing personal finances. One method of doing this was using Jupyter Notebook and running some Matplotlib plots, which I explain on &lt;a href="https://github.com/perryraskin/TransFormer" rel="noopener noreferrer"&gt;this GitHub repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For a while now I've been meaning to integrate Plaid into a web app and try manipulating some financial data. After inevitably using it in the many budgeting apps I've encountered, I knew I had to give it a try myself. Currently I use &lt;a href="https://copilot.money" rel="noopener noreferrer"&gt;Copilot&lt;/a&gt;, an iOS budgeting app that uses Plaid, and I absolutely love it. My code MRJA4Q will get you &lt;strong&gt;3 months free&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;I followed a &lt;a href="https://medium.com/@dereksams/building-a-react-app-with-the-plaid-api-93e45ae61b58" rel="noopener noreferrer"&gt;blog post&lt;/a&gt; by Derek Sams that showed me how to get a React app running with Plaid. To get it working with Next.js, I had to make a few changes you may notice if you decide to compare the two.&lt;/p&gt;

&lt;h2&gt;
  
  
  Our Starter App
&lt;/h2&gt;

&lt;p&gt;What we're focusing on here is to simply get Plaid working with a working React app. It will make a call to Plaid's transactions API and display transactions to the console. Of course once you get this done you can build upon this thing to make it do some really useful stuff!&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Set Up
&lt;/h2&gt;

&lt;p&gt;If you'd like, you can get started from scratch using &lt;a href="https://nextjs.org/learn/basics/getting-started/setup" rel="noopener noreferrer"&gt;Next.js's guide&lt;/a&gt; on starting a new project. For this post I'll focus on the &lt;a href="https://github.com/perryraskin/nextjs-plaid-starter" rel="noopener noreferrer"&gt;boilerplate repo&lt;/a&gt; I published to GitHub. Once you clone the repo you'll want to run &lt;code&gt;npm install&lt;/code&gt; in the root folder to get all set up. Please see the ReadMe file for more information.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Code
&lt;/h2&gt;

&lt;p&gt;Notice our API routes in &lt;code&gt;/pages/api&lt;/code&gt;. Next.js automatically handles routing for us simply based on files it detects in this folder, like magic! We will take advantage of this along with our handy fetching utility called &lt;code&gt;isomorphic-unfetch&lt;/code&gt;. These are important for working with Plaid's API.&lt;/p&gt;

&lt;h3&gt;
  
  
  The API
&lt;/h3&gt;

&lt;p&gt;Let's take a look at the API in &lt;code&gt;/pages/api/plaid/index.js&lt;/code&gt;. First we need to import &lt;code&gt;next-connect,&lt;/code&gt; which will allow us to utilize the Next.js request handler. In our case, we will be sending a &lt;code&gt;POST&lt;/code&gt; request. Then of course we'll need &lt;code&gt;plaid&lt;/code&gt; for connecting to Plaid's API, and &lt;code&gt;moment&lt;/code&gt; to do work with a few dates.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;nextConnect&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next-connect&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;plaid&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;plaid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;moment&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;moment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we need to initialize some variables. As our &lt;code&gt;.env&lt;/code&gt; file defines the API tokens received from Plaid, I defined them here. These are used to create the Plaid client object, which allows us to exchange keys and grab transactions as will be seen later in the file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PLAID_CLIENT_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PLAID_CLIENT_ID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PLAID_SECRET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PLAID_SECRET_SANDBOX&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PLAID_PUBLIC_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PLAID_PUBLIC_KEY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PLAID_ENV&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PLAID_ENV&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;ACCESS_TOKEN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;ITEM_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Initialize the Plaid client&lt;/span&gt;
    &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;plaid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;PLAID_CLIENT_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;PLAID_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;PLAID_PUBLIC_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;plaid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;environments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;PLAID_ENV&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2019-05-29&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;clientApp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Plaid Quickstart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;nextConnect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;handler.post&lt;/code&gt; will begin the API call. We are doing two things here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Calling &lt;code&gt;client.exchangePublicToken&lt;/code&gt; to provide us with the access token&lt;/li&gt;
&lt;li&gt;Calling &lt;code&gt;client.getTransactions&lt;/code&gt; to return all transactions from the past 30 days&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once we receive the access token from &lt;code&gt;client.exchangePublicToken&lt;/code&gt; we will use it when we call &lt;code&gt;client.getTransactions&lt;/code&gt;. That's pretty much all that's going on here. The rest of the code is console logging the results so we can see what's going on as it happens.&lt;/p&gt;

&lt;p&gt;Upon a successful response, we will receive the following JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Success!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;access_token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ACCESS_TOKEN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;item_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ITEM_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;transactions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;transactions&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you use Postman, you should see this response. Clicking the "View Transactions" button after you connect the (sandbox) bank account, the dev console will output the &lt;code&gt;{ transactions: transactions }&lt;/code&gt; part of that response. More on front end aspects in the next section. Be sure to use the following sandbox credentials, provided by Plaid:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;User ID:&lt;/strong&gt; user_good&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Password:&lt;/strong&gt; pass_good&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Front End Component
&lt;/h3&gt;

&lt;p&gt;I recently learned that if we want to work with state when using Next.js, we need to call &lt;code&gt;useState()&lt;/code&gt;. For our little project, we'll need &lt;code&gt;transactions&lt;/code&gt; to be stateful.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;transactions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTransactions&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it! We're basically just declaring a variable along with a matching setter for its state. In this case, &lt;code&gt;transactions&lt;/code&gt; is the variable and &lt;code&gt;setTransactions&lt;/code&gt; is the setter function. If you are familiar with deconstructing, you cant think about it as deconstructing the imported &lt;code&gt;useState&lt;/code&gt; functionality.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleOnSuccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;public_token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// send token to client server&lt;/span&gt;
        &lt;span class="nx"&gt;fetchSwal&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/plaid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;public_token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;public_token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;})&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nf"&gt;setTransactions&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;transactions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transactions&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the function that handles the click of our “Connect your bank!” button to grab transactions. You'll see in the &lt;code&gt;PLink&lt;/code&gt; component how it all comes together. This basically just makes an API call to grab the transactions from the account you just logged into through Plaid! Once we have the transactions, our &lt;code&gt;setTransactions&lt;/code&gt; setter function sets the state to the value we just received.&lt;/p&gt;

&lt;p&gt;We will then print the transactions to the dev console (in Chrome, for example) by clicking the "View Transactions" button.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;transactions:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;transactions&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;It's amazing that we have access to such a great API like Plaid. It really allows us devs to get creative with all kinds of data.&lt;/p&gt;

&lt;p&gt;Feel free to leave comments and let me know how this went for you! I'd love to hear about any cool features you implemented following this initial setup.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>plaid</category>
      <category>finances</category>
      <category>react</category>
    </item>
    <item>
      <title>Beautify code in your Next.js blog</title>
      <dc:creator>Perry Raskin</dc:creator>
      <pubDate>Wed, 11 Mar 2020 14:54:43 +0000</pubDate>
      <link>https://dev.to/perryraskin/beautify-code-in-your-next-js-blog-4a4d</link>
      <guid>https://dev.to/perryraskin/beautify-code-in-your-next-js-blog-4a4d</guid>
      <description>&lt;p&gt;It definitely took me way too long to get code blocks correctly highlighted on my blog. Next.js seems to have less tutorials out there in general, especially for specific use cases like these. I hope to fix that, at least a little bit, with my own blog. As I experience issues and overcome each challenge, my plan is to write up a post about it. Here's #1!&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Background
&lt;/h2&gt;

&lt;p&gt;As a starting point, I want to outline the architecture of my website. As Next.js goes, I have page components in the &lt;code&gt;/pages&lt;/code&gt; directory. Blog posts are generated dynamically via the &lt;code&gt;/pages/blog/[slug].tsx&lt;/code&gt; page, where the &lt;code&gt;getInitialProps&lt;/code&gt; function pulls content from the &lt;code&gt;.md&lt;/code&gt; files located in the &lt;code&gt;/posts&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;If this is new to you, there are tutorials that explain how this works (e.g. &lt;a href="https://nextjs.org/learn/basics/create-dynamic-pages" rel="noopener noreferrer"&gt;Next.js docs&lt;/a&gt;). Feel free to also view the code on the &lt;a href="https://github.com/perryraskin/raskin.me" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before Highlight.js
&lt;/h2&gt;

&lt;p&gt;For a visual, below is what the &lt;code&gt;BlogPostTemplate&lt;/code&gt; component looked like before I did anything fancy. I will only include the relevant code to keep it short, but feel free to view the &lt;a href="https://github.com/perryraskin/raskin.me/blob/master/pages/blog/%5Bslug%5D.tsx" rel="noopener noreferrer"&gt;entire file&lt;/a&gt; in the repo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;article&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mb-10 markdown&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-5xl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;frontmatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/header&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mb-5 my-auto text-sm font-semibold text-neutral-400&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;reformatDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;frontmatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ReactMarkdown&lt;/span&gt; 
      &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;markdownBody&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/article&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that this code simply applies a title, date, and the contents of the &lt;code&gt;.md&lt;/code&gt; file. By default, inline code and code blocks were not nicely styled, and of course I wasn't satisfied with that. Luckily, &lt;code&gt;react-markdown&lt;/code&gt; takes an optional parameter called &lt;code&gt;renderers&lt;/code&gt; where we can provide a custom style to HTML tags of our choosing. This is where it got confusing - I had to dive into the &lt;a href="https://github.com/rexxars/react-markdown/blob/master/src/renderers.js" rel="noopener noreferrer"&gt;source code&lt;/a&gt; to figure out what exactly I needed to pass to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The CodeBlock Component
&lt;/h2&gt;

&lt;p&gt;First and foremost, make sure you have your imports for highlight.js. You can choose any theme from the &lt;code&gt;/styles&lt;/code&gt; folder that's provided.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Highlight&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-highlight&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../node_modules/highlight.js/styles/nord.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After &lt;strong&gt;a lot&lt;/strong&gt; of trial and error, I realized I needed to create a custom component to pass to &lt;code&gt;renderers&lt;/code&gt;. I'm sure there are other ways to do this, but this made the most sense to me, and it worked quite nicely.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;CodeBlockProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CodeBlock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextPage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CodeBlockProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Highlight&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Highlight&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;br&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since the &lt;code&gt;code&lt;/code&gt; parameter of &lt;code&gt;renderers&lt;/code&gt; requires a component with a &lt;code&gt;&amp;lt;code&amp;gt;&lt;/code&gt; element that's inside of a &lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt; element, this is what I came up with. &lt;code&gt;&amp;lt;Hightlight /&amp;gt;&lt;/code&gt; includes all of that, so I added it inside this component, and passed the &lt;code&gt;value&lt;/code&gt; (the actual code) as props.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ReactMarkdown&lt;/span&gt; 
  &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;markdownBody&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;renderers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
    &lt;span class="na"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CodeBlock&lt;/span&gt;
  &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, I simply passed the &lt;code&gt;CodeBlock&lt;/code&gt; component to &lt;code&gt;code&lt;/code&gt; and finally it worked! Just be sure you don't have PurgeCSS stripping your highlight.js CSS, and you should be good to go.&lt;/p&gt;

&lt;p&gt;--&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I also blog on my &lt;a href="https://raskin.me" rel="noopener noreferrer"&gt;personal site&lt;/a&gt;, where this post was &lt;a href="https://raskin.me/blog/beautify-code-in-your-next-js-blog" rel="noopener noreferrer"&gt;originally published&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>highlightjs</category>
      <category>nextjs</category>
      <category>react</category>
      <category>tailwindcss</category>
    </item>
  </channel>
</rss>
