DEV Community

Deniz
Deniz

Posted on • Originally published at blog.fregram.com on

Old Blog: Gatsby Update!

First post on dev.to, I'm not much a writer but with this post I'm plaining to motivate myself to write regularly. Hopefully this time I will be successful. So let's start.

Why Change? Why Gatsby?

Old blog was based off Pelican Static Site Generator (Old Blog source can be found in the source branch). I don't used much but it was rock solid, after 3 years still working and in usable form. Although I'm not sure what can go wrong in a static site but, you'll never know.

So why the change? Mainly to write this post. Also old style was getting really old, I didn't change much but new style look minimal and modern I think? (I'm not good at designing). Another problem was that I haven't dealt with python in a long time, and I'm not motivated to edit 4-5 year old python project. So as a solution decided to move blog something new. For a small project (of course half completed project) I played with Hugo, It was really fast as claimed but Go was not for me. Then I saw Gatsby a new Hype in the static site scene (like 2 years ago), It had every popular buzz word at the time React, performance, scalability. I was ready to join Hype-Train and play with Gatsby but there was no opportunity (AKA to lazy to do hobby projects). But now I'm ready to join. Also at work I'm using Typescript and React so it was easy to join on train (probably the main reason)

How?

I'm not going to write as detailed a tutorial, cause Gatsby has enough documents and tutorials. Only going to explain some tips and tricks I used.

Theme/Starter

I used Gatsby Starter Chronoblog template with minimal edits. With shadowing and override features, It was fairly easy.

Multiple Authors (sort of)

Old blog was combined effort with my friend, I think there is only 1 post from him but I wanted to preserve it.

first we need to add author field to post frontmatter. So override postQuery in post template with creating src\gatsby-theme-chronoblog\templates\post.js file


import { graphql } from 'gatsby';

import Post from 'gatsby-theme-chronoblog/src/components/post';

export default Post;

export const postQuery = graphql`

 query($id: String!) {

 mdx(id: { eq: $id }) {

 id

 excerpt

 frontmatter {

 category

 author

 title

 date

 description

 tags

 cover {

 childImageSharp {

 fluid(maxWidth: 768, quality: 90) {

 ...GatsbyImageSharpFluid\_withWebp

 presentationWidth

 presentationHeight

 src

 }

 resize(width: 768) {

 src

 }

 }

 }

 }

 fields {

 slug

 }

 body

 }

 }

`;

Enter fullscreen mode Exit fullscreen mode

Now we have author metadata but we need to display it in website, For this Chronoblog has a post-footer.mdx.

create post-footer component in src\gatsby-theme-chronoblog\post-footer.mdx. Then we can easily access global site configuration and post data from component props. So I added a hack with default Chronoblog components, if post has different author than site author it displays author name from post frontmatter, else it's uses beautiful default AuthorBanner component from Chronoblog. Of course with this approach guest authors banner pretty dull looking but for now its good enough.


<div>

{props.postData.frontmatter.author && 

props.postData.frontmatter.author !== props.siteMetadata.author ? 

<AuthorBanner>

<div>

<AuthorBannerHeading>{props.postData.frontmatter.author}</AuthorBannerHeading>

</div>

</AuthorBanner>

:

<AuthorBanner></AuthorBanner>

}</div>

Enter fullscreen mode Exit fullscreen mode

Disqus comments

I think there better solutions but old blog was using and I'm to lazy to migrate 4 old comments to a new system.

There a plugin gatsby-plugin-disqus

add disqus to plugins configuration in gatsby-config.js


plugins: [

...,

{

 resolve: `gatsby-plugin-disqus`,

 options: {

 shortname: `yourshortname`

}

}

]

Enter fullscreen mode Exit fullscreen mode

then add Disqus component to post-footer component in src\gatsby-theme-chronoblog\post-footer.mdx to show comments


import { Disqus } from 'gatsby-plugin-disqus';

<Disqus

config={{

url: props.siteMetadata.siteUrl + props.postData.fields.slug,

title: props.postData.frontmatter.title,

id: props.postData.id

}}

/>

Enter fullscreen mode Exit fullscreen mode

Travis auto build and deploy to github pages

Automation is god send!

First we need ghpages tool, run npm install gh-pages --save-dev in project dir to add it. Then a deploy script for Travis, we can use npm scripts

add this to scripts in package.json (of course update repo url to your repo)


"travis-deploy": "gatsby build --prefix-paths && gh-pages -d public -r https://$GH\_TOKEN@{yourgitrepo}",

Enter fullscreen mode Exit fullscreen mode

then create a travis.yml


language: node\_js

before\_script:

- npm install -g gatsby-cli

node\_js:

- "10"

deploy:

provider: script

script: npm i --quiet && npm run travis-deploy

skip\_cleanup: true

on:

branch: v2

Enter fullscreen mode Exit fullscreen mode

We are ready to connect our repo to travis. After connecting repo don't forget to add your github auth token GH_TOKEN in Travis Environment Variables settings. Then we are done, now every time you push a change to repo travis will build and push to gh-pages branch.

Dev.to cross posting dream

Yeah I don't post much, but I want those sweet views.

So Dev.to supports RSS import, It should be easy right? No It won't easy. Because of code highlighting or Chronoblog theme; RSS html output is full off inline styles, so Dev.to's html to markdown converter freaks out and displays bunch of empty html tags in markdown. To fix it first I tried to give raw markdown output in RSS but rendering mdx pain in the butt and also looks like Dev.to only supports html in RSS. So for now I removed style tags and css classes from html output, yeah probably it will break RSS readers but who is using them? (a controversial topic maybe?)

of course gatsby has RSS feed plugin

add RSS feed plugin plugins configuration in gatsby-config.js


{

 resolve: `gatsby-plugin-feed`,

 options: {

 query: `

 {

 site {

 siteMetadata {

 siteTitle

 siteDescription

 siteUrl

 site\_url: siteUrl

 description siteDescription

 title: siteTitle

 }

 }

 }

`,

 feeds: [

{

serialize: ({ query: { site, allMdx } }) => {

return allMdx.edges.map((edge) => {

return Object.assign({}, edge.node.frontmatter, {

 description: edge.node.excerpt,

 date: edge.node.frontmatter.date,

 author: edge.node.frontmatter.author,

 title: edge.node.frontmatter.title,

 url: site.siteMetadata.siteUrl + edge.node.fields.slug,

 guid: site.siteMetadata.siteUrl + edge.node.fields.slug,

 custom\_elements: [

{

'content:encoded': edge.node.html

.replace(/<style((.|\n|\r)\*?)<\/style>/gi, '')

.replace(/class="(.\*?)"/gi, '')

},

{

 tags:

 edge.node.frontmatter.tags &&

 edge.node.frontmatter.tags.join(',')

},

{

 category:

 edge.node.frontmatter.tags &&

 edge.node.frontmatter.tags.join(',')

}

]

});

});

},

 query: `

 {

 allMdx(

 limit: 1000,

 sort: { order: DESC, fields: [frontmatter\_\_\_date] },

 filter: { fields: { type: { eq: "posts" } } }

 ) {

 edges {

 node {

 excerpt

 html

 id

 fields {

 slug

 type

 }

 frontmatter {

 author

 title

 date

 link

 draft

 tags

 }

 body

 }

 }

 }

 }

`,

 output: '/rss.xml',

 title: `Fregram Blog`

}

]

}

}

Enter fullscreen mode Exit fullscreen mode

Probably half of tags in the RSS is useless but I did not found a good document about it, so left all of them. Main magic happens in serialize function using regex replace removes style tags and css classes from html, If you have a working configuration you only need to add this change.


edge.node.html

.replace(/<style((.|\n|\r)\*?)<\/style>/gi, '')

.replace(/class="(.\*?)"/gi, '')

Enter fullscreen mode Exit fullscreen mode

also for tags support you need to comma separated list so add these too


{

tags:

 edge.node.frontmatter.tags &&

 edge.node.frontmatter.tags.join(',')

},

{

category:

 edge.node.frontmatter.tags &&

 edge.node.frontmatter.tags.join(',')

}

Enter fullscreen mode Exit fullscreen mode

In Conclusion

Everything is better and I'm happy

To tell the truth it's not much different from old Pelican setup, maybe more modern. Like with mdx and shadowing gatsby look more easy to customize, but as a Static Website Generator I think they are same. Of course if you are using or interested in React and graphql (although you don't see react much, it's mostly hidden especially using themes) it's good weekend project.

Top comments (0)