New Features for this Blog

2019 has been a year of gatsby updates for this site. So, I wanted to end this year with the same spirit. And, I am hoping this is going to be the begining of maturity of the looks and features of this blog. In the upcoming year, I plan to focus mainly on content, specifically related to medicine, AI and proramming.

TLDR

Updates to this blog UI:

Here is a list of all the new features that I have lately added to this:

  • updated codeblocks with copy and language indicator
  • Medium-like highlight to share text feature
  • Simplify navigation bar links
  • Update footer to include social links
  • Use postlist for similar posts
  • Add substack subscription
  • Add goatcounter for analytics
  • CSS updates for blokquote, TLDR, Update components etc.
  • fix edit on github links

In the following, I want to highlight some of these in little more detail:

Updated codeblocks component

One of the biggest updates that I made here has been in code blocks. Till now, I have been using the gatsby-remark-prismjs plugin. However, for mdx files, the recommended way is to use the prism-react-renderer library, as this also supports more advanced features like use of live code blocks via react-live. This approach additionally provides a lot of freedom to any user-defined features like copy to clipboard, language indicator etc.

I have followed following gatsby themes to create a Code component that can have features like copy to clipboard, language indicator etc: gatsby-theme-minimal-blog, and gatsby-theme-novela.

Here is a partial peek at my final solution:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
const Copy = ({ toCopy }) => {
  const [hasCopied, setHasCopied] = useState(false);

  function copyToClipboardOnClick() {
    if (hasCopied) return;

    copyToClipboard(toCopy);
    setHasCopied(true);

    setTimeout(() => {
      setHasCopied(false);
    }, 2000);
  }

  return (
    <CopyButton onClick={copyToClipboardOnClick} data-a11y='false'>
      {hasCopied ? (
        <>
          Copied <CopiedIcon fill='#6f7177' />
        </>
      ) : (
        <>
          Copy <CopyIcon fill='#6f7177' />
        </>
      )}
    </CopyButton>
  );
};

const Code = ({ codeString, className: blockClassName, metastring = ``, ...props }) => {
  if (props['react-live']) {
    return <LazyLiveProvider code={codeString} noInline={false} theme={theme} />;
  }

  const [language, { title = `` }] = getParams(blockClassName);
  const shouldHighlightLine = calculateLinesToHighlight(metastring);

  return (
    <LazyHighlight {...defaultProps} code={codeString} language={language} theme={theme}>
      {({ className, style, tokens, getLineProps, getTokenProps }) => (
        <React.Fragment>
          {title && (
            <div className='code-title'>
              <div>{title}</div>
            </div>
          )}
          <div className='gatsby-highlight' data-language={language}>
            <pre className={className} style={style}>
              <Copy toCopy={codeString} />
              {tokens.map((line, i) => {
                const lineProps = getLineProps({ line, key: i });
                if (shouldHighlightLine(i)) {
                  lineProps.className = `${lineProps.className} line-highlight`;
                }
                return (
                  <div {...lineProps}>
                    {line.map((token, key) => (
                      <span {...getTokenProps({ token, key })} />
                    ))}
                  </div>
                );
              })}
            </pre>
          </div>
        </React.Fragment>
      )}
    </LazyHighlight>
  );
};

export default Code;

Notice, how I have highlighted the filename of the component and the interesting sections of the code.

The first highlighted section implements the copy to clipboard function. The second section is the actual implementation of the Code component.

Finally to complete the implementation, two more changes are needed:

  • Add pre and code components to MDXProvider in the post template file, and
  • Add relevant css

If you are interested in details of the implementation for your own sites, please take a closer look at the details of the css at ./src/styles/components/prism.scss.

You can see my github repository for complete details of the implementation.

Finally, this implementation also supports live coding via the react-live library.

Medium-like highlight to share text

A cool feature in Medium is the highlight menu that pops up when you select some text. This menu contains buttons that allow you to perform certain actions on the selected text like highlight and share.

Picture Courtesy: https://maxart2501.github.io

Picture Courtesy: https://maxart2501.github.io

You can have a look at my implementation here.

And of course, you can see it in action if you try to select and highlight some text. I only provide options for facebook, twitter and LinkedIn sharing though.

Add goatcounter for analytics

goatcounter.com is an open source, privacy aware, extremely light web analytics service that doesn’t need a GDPR notice. To me this sounded like a perfect replacement for google analytics.

The setup is extremely simple - you sign-up and get a script to include on your pages. The problem that I faced was how to include bare bones Javascript code in a react component.

I ended up using ScriptTag from the react-script-tag library. This just required me to save the javascript code in a separate file in static folder and include that using ScriptTag in the layout file. You can have a peek at my implementation in more detail here.

And of course, you can see my public dashboard right here.

Add substack subscription

I have always wanted to provide a timely update about any new posts and updates to my regular followers. I first tried mailchimp, however, never felt satisfied with it. Looking for alternatives brought me to substack. I found this to be a modern solution that fit my needs. Now, you can see a link to my subscription to all pages, including one right below.

This was all the major changes that I made to the codebase. Other than these major changes, there are also many small changes to make the code cleaner and more generic.

Here is hoping to bring to an end to any further updates to the looks of this blog. Please look forward to content updates on major topics like medicine, deep learning and programming. Do not forget to subscribe to my newsletter below!