How I use Gatsby to develop performant marketing websites optimized for SEO

A high level overview of how I would typically set up a static site for marketing that is performant, accessible, and optimized for SEO. This article assumes that the reader is already familiar with React.
Prologue
There likely might be better ways to do some of what I explain below, but this is what has worked very well for me during my freelance career in my attempt to find the balance between simplicity, quality, and cost-effectiveness. Always do your own research and talk to other engineers about ways they try to build the most optimal websites. Each circumstance is unique and it takes time to decide which technologies may be useful which ones may be overkill while adding unnecessary complexity.
This article is specifically for my junior engineer friends who are fresh out of bootcamps and may want to work on projects to expand their portfolio and web development skills. Maybe you've worked on a static site at a company and are familiar with how to build and style components, but have never needed to work on devOps.
It's also essential to understand that the web development ecosystem is fast-paced. By the time of reading, some information might have changed or evolved. It's always a good idea to check the official documentation or resources for any updates. Hope anyone may find this information useful!
1. Why Gatsby?
Gatsby is not just another static site generator; it's a PWA (Progressive Web App) generator. What this means for you is an extremely fast-loading site that engages your users from the first click.
Gatsby vs. Next.js for Marketing Sites: Performance: At its core, Gatsby pre-builds page content, making site load times lightning-fast. This is invaluable for marketing sites where capturing attention immediately can make all the difference.
SEO: Gatsby sites are SEO-friendly by design. The entire content gets compiled beforehand, making it effortlessly scannable and indexable by search engines, which often equates to higher organic traffic.
Simplicity: Gatsby removes the overhead of server management. For pure marketing sites, this means less maintenance, fewer points of failure, and an overall streamlined developer experience. Next.js is a fantastic tool, especially for server-side rendered applications. Still, its myriad of features can be overkill for a straightforward marketing site. As Addy Osmani once said:
One of the most important skills in Software Engineering is being able to identify essential complexity and eliminate unnecessary complexity. Minimize creating complexity at all where possible.
2. Setting the Stage with Gatsby
Beginning with Gatsby is straightforward. The command:
gatsby new your-project-name
not only sets up a new Gatsby site but also provides you with a modern frontend setup, including React, Webpack, and GraphQL. This gives you a solid starting point to build and customize your marketing site.
3. Syncing with GitHub
I assume that anyone reading this is familair with GitHub as a version control system and hopefully doesn't need me to explain how to connect your project to a repository on GitHub, but just in case here is this resource:
4. Hosting on AWS S3
Vercel and Netlify are great platforms that integrate seamlessly with your react projects. However, AWS S3 offers unparalleled flexibility and cost-effectiveness, especially for static sites generated by Gatsby. The initial setup on AWS might appear daunting, but the payoff in terms of scalability, performance, and cost is substantial.
Configuring a static website on Amazon S3
5. Security First: Using GitHub Secrets
API keys or AWS access credentials must be kept confidential. GitHub Secrets is a mechanism that lets you securely store sensitive information. By using secrets, you ensure that even if someone accesses your repository, they won't have the keys to your kingdom. You can use github actions to add these secrets to your production and development environments so that they can be accessed when you deploy your site to AWS, however you'll still want to keep your environment variables in a .env.development when developing in a local environment.
Workflow ex:
jobs:
build_and_deploy:
runs-on: ubuntu-latest
env:
GSAP_AUTH_TOKEN: ${{ secrets.GSAP_AUTH_TOKEN }}
CONTENTFUL_ACCESS_TOKEN: ${{ secrets.CONTENTFUL_ACCESS_TOKEN }}
CONTENTFUL_SPACE_ID: ${{ secrets.CONTENTFUL_SPACE_ID }}
6. Mastering GitHub Workflows
Automating deployment processes is the way to go for efficiency. Here's a closer look:
auto-deploy-prod.yml: This is your lifeline for keeping the production site updated. Especially when your content is linked to an external source, any change there should reflect on your site without manual intervention.
deploy-dev.yml: This workflow is especially crucial for team-based projects. Every time you raise a pull request, it automatically generates an AWS build link. This link provides a live preview of the changes, invaluable for designers, developers, and stakeholders for feedback. It also ensures that before the changes are merged into the main codebase, they undergo thorough testing in a near-production environment.
The breakdown of the deploy-dev.yml workflow:
Set dev folder: It creates a unique folder for every pull request. This ensures every change gets its isolated environment for testing.
- name: Set dev folder
run: |
echo "::set-output name=DEV_FOLDER::$(echo ${GITHUB_REF:11} | sed 's|/|-|')"
id: <yourID>
Install dependencies: Before the build begins, dependencies are installed. This ensures the build process has all it needs.
- name: Install dependencies
run: |
echo "${{ steps.<yourID>.outputs.DEV_FOLDER }}"
yarn install
Build site: Here, the static site gets built with the pull request changes.
- name: Build site
run: |
echo "GATSBY_ACTIVE_ENV: $GATSBY_ACTIVE_ENV"
echo "GATSBY_DEV_PATH-WF: ${{ env.GATSBY_DEV_PATH }}"
GATSBY_DEV_PATH=${{ steps.<yourID>.outputs.DEV_FOLDER }} yarn build:dev:path
Deploy static site to S3 bucket: Once built, this step deploys the site to the specific AWS S3 location, making it ready for review.
- name: Deploy static site to S3 bucket
run: |
echo "$DEV_FOLDER"
echo "Host: ${{ secrets.AWS_DEV_BUCKET_NAME }}/${{ steps.<yourID>.outputs.DEV_FOLDER }}"
aws s3 sync ./public/ s3://${{ secrets.AWS_DEV_BUCKET_NAME }}/${{ steps.<yourId>.outputs.DEV_FOLDER }} \
--delete \
--metadata-directive REPLACE \
--expires 2100-01-01T00:00:00Z \
--cache-control max-age=31536000,public \
--acl public-read
deploy-prod.yml: Upon merging a pull request to the production branch, this workflow deploys the changes. This ensures your live site always represents the latest, reviewed, and approved version of your content.
s3-cleanup: Housekeeping is crucial. Over time, the many build links generated by pull requests can clutter your AWS bucket and rack up costs. This workflow cleans up by deleting outdated builds, ensuring you're only billed for what you actively use.
name: Cleanup S3
on:
delete:
jobs:
cleanup_s3:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Set up AWS CLI
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-west-1
- name: Set dev folder
run: |
BRANCH_NAME=$(echo ${{ github.event.ref }} | sed 's|refs/heads/||' | sed 's|/|-|')
echo "DEV_FOLDER=$BRANCH_NAME" >> $GITHUB_ENV
- name: Debugging information
run: |
echo "S3 Bucket: ${{ secrets.AWS_DEV_BUCKET_NAME }}"
echo "Folder to delete: ${{ env.DEV_FOLDER }}"
echo "Full S3 path: s3://${{ secrets.AWS_DEV_BUCKET_NAME }}/${{ env.DEV_FOLDER }}"
- name: Delete S3 folder
run: aws s3 rm s3://${{ secrets.AWS_DEV_BUCKET_NAME }}/${{ env.DEV_FOLDER }} --recursive
Here are two articles on how to set up an AWS deployment workflow for your projects:
Deploy React App to Amazon S3 Using Github Actions
How to deploy a React application to Amazon S3 and GitHub actions
7. Winning the SEO Game with Gatsby
Search Engine Optimization isn't just about ranking higher; it's about delivering a better user experience. With Gatsby's built-in features and the power of plugins like gatsby-plugin-react-helmet, you can dynamically control the head of your document. This allows search engines to better understand and rank your content, driving organic traffic.
8. Delving into Image Optimization
Images, while crucial for user engagement, are often the largest files on web pages. Inefficient handling can slow down your site drastically.
Gatsby provides tools like <GatsbyImage/> which supersede the regular <img/> tag. Here's why:
Optimized Images: Gatsby processes images at build time, generating optimized versions for various screen sizes and resolutions.
Lazy Loading: Images load as users scroll, ensuring faster initial page loads.
Blurred Uploading: Gatsby provides a low-res placeholder, which smoothly transitions to the high-res image once loaded. This prevents the page layout from jumping, enhancing user experience.
Reduced Bandwidth: By serving images tailored to the user's device, unnecessary data consumption is avoided.
Remember to always include an alt tag with your images. It's a simple step that greatly aids accessibility and further boosts SEO.
Learn about Core Web Vitals to optimize your website
9. Leveraging Cloudflare for Site Distribution and DNS Management
Cloudflare has revolutionized the way developers think about web performance and security. Distributing your site via Cloudflare and managing your DNS through their platform brings a multitude of benefits.
1. CDN: With data centers in over 200 cities, Cloudflare caches your content worldwide, ensuring swift load times and saving on bandwidth costs.
2. DDoS Protection: Cloudflare provides robust defenses against harmful DDoS attacks, automatically detecting and mitigating potential threats.
3. DNS Management: Benefit from fast and reliable DNS resolutions thanks to Cloudflare's extensive DNS network, coupled with the security of DNSSEC.
4. Web Optimizations: Features like Auto Minify and Rocket Loader reduce file sizes and improve load times for pages with JavaScript.
5. SSL/TLS Encryption: Secure your user's data with free SSL encryption, enhancing user trust and SEO rankings.
6. Cost-Efficiency: Many of Cloudflare's essential features, like CDN and DDoS protection, come at no cost, making it an excellent choice for developers on a budget.
Incorporating Cloudflare into your Gatsby strategy not only ensures enhanced speed and security but also provides you with invaluable insights into your site's traffic, making it an indispensable tool for any developer.
I'd be remissed if I didn't note that CloudFront is another AWS tool that offers robust content delivery network services, seamlessly integrating with other AWS products and ensuring lightning-fast and secure distribution of your website content to a global audience. However, CloudFront does require a bit more effort to setup compared to CloudFlare with a more complex pricing.
For a simple website that doesn't require much of a complex need for cache purging, I tend to lean toward CloudFlare for a simple setup, security, and DNS, but depending on your needs CloudFront may be a better and more streamlined option. Find your own preference.
How to Serve Files from S3 via CloudFlare
Conclusion
Choosing Gatsby for your marketing website provides you with a toolkit designed to optimize performance, SEO, and user experience. While Next.js excels in more dynamic scenarios, Gatsby’s pre-rendering and optimization features make it a frontrunner for content-centric sites. Dive deeper, explore its capabilities, and leverage Gatsby to its fullest potential!