Back to changelog

Building and Designing a Portfolio Site Using Gatsby JS and Cosmic

Jacob Knaack's avatar

Jacob Knaack

May 13, 2019

cover image

Creating / updating our portfolios is a necessary evil these days.  Places change, people change, and thus the cycle of content creation and management churns continuously.  When you find yourself in need of  a portfolio redesign, there are tons of tools and services to consider.  One that should currently peak your interest is the Gatsby JS static site generator along with a headless CMS, like Cosmic.  Today, with these two tools, we will create a working portfolio ready for continuous deployment, with the power to be rebuilt when content changes are made.


Gatsby Portfolio Site Demo

Download the Codebase 

0.0 Before We Start

We are creating a portfolio site mostly with static data, but it would nice to be able to easily modify the content of our site without needing to modify a bunch of source code.  So we are building a client that consumes content stored on a Content Management Service and programmatically displays it at whatever URL we choose. 

0.1 Tools We Are Using

  • Gatsby JS - This is a static site generator that will automatically fetch new data and rebuild our site files when changes are made to our content.  Comes bundled with data fetching wizardry GraphQL and the ever present React JS front end framework.

  • Cosmic - Our Content Management Service that will store all the information we need about our site.  Cosmic offers very flexible data model definition that will allow us to store all types of information, from iterables to simple text fields and HTML content.   NOTE! - In order to follow along with this tutorial you will need to create a bucket on Cosmic and fill it with the appropriate data objects.

  • RSuite - A library of pre-styled components that works with react to give us pre-styled components.  This will allow us to use components that look great out of the box, while also giving us flexibility to make adjustments as needed.

  • Netlify (Optional) - A deployment service that will let us hook directly into a git repository.  Using this we can configure webooks for rebuilding static files as well as make automatic deploys when source code changes occur.

Let's go ahead and begin configuring our setup.

1.0 Installation and Setup

We only have a few software requirements needed to start building. Mainly we need Node JS, either npm or yarn, and we will be using git to do some deployment things on Netlify if you so choose.

1.1 Initializing our Project

Once you get those installed, we can begin setting up our development environment.  Gatsby uses a very handy dandy CLI to allow us to bootstrap our project with a project directory ready to build and serve from a Node environment.

If you don't have the CLI you can install it with a simple npm terminal command:

$npm install -g gatsby-cli

This will take a moment to install but after a few seconds you will have access to gatsby terminal command which we can use to initialize our project:

$gatsby new gatsby-portfolio

Now we have a directory called gatsby-portfolio in the location you ran the gatsby command, change to that directory and list its contents:

$cd gatsby-portfolio/ && ls -la

You should see a list of folders and files similar to this:

├── node_modules
├── src
├── .gitignore
├── .prettierrc
├── gatsby-browser.js
├── gatsby-config.js
├── gatsby-node.js
├── gatsby-ssr.js
├── package-lock.json
├── package.json

open up package.json and we will see we have some terminal scripts that we can now use to build / serve our project. Try running the start script in your terminal:

$npm start


$yarn start

After a few seconds we should see a success message in our terminal and we should be able to view our initial project view on our localhost, your should see something like this:

Great, now press ctrl + C within your terminal to stop the development server and we are now ready install our node libraries.

1.2 Installing our Libraries

We require a few plugins from Gatsby to allow our Graphql queries to run, as well as a few extras for environment configuration and our component library RSuite.  From within your project directory, we need to run some terminal commands to get our js libraries:

$yarn add rsuite dotenv gatsby-source-cosmicjs gatsby-plugin-sass gatsby-plugin-less node-sass less

Let's go through these and talk about what we are adding to our project here:

  • rsuite - our component library that I mentioned above.  Installing this let's us import js classes and insert pre-styled React components.
  • dotenv - Allows us to configure our source code with sensitive api keys, token, whatever that may change between developers but should be present when the source code is built.
  • gatsby-source-cosmicjs - a gatsby plugin that will let us easily make graphql requests to the Cosmic graphql API.
  • gatsby-plugin-sass / gatsby-plugin-less / node-sass / less - Gatsby plugins and styling libraries that will let us use .scss and .less files.  These will allow us to import rsuite styling specs and bundle them properly on build.

1.3 Configuring Gatsby

In order for Gatsby to be able to build our html files, we need to fetch data from Cosmic and build each page using the data graphql retrieves.  Let's go ahead and open gatsby-config.js and add our installed packages:

We have added our plugins for sass and less, and also added our gatsby-source-cosmicjs plugin.  You'll notice that we are using some environment variables to configure this plugin so we need to add a hidden file that will store these variables.

$touch .env

Now add your variables to this file and dotenv will take care of defining these using line 1 of our gatsby-config.js file.  You can find the value to assign to these variables from within your Cosmic bucket: Bucket Name > Dashboard > Settings > Basic Settings:

Now we are ready to build!

2.0 Building Our Components

So what are we building exactly.  Well, basically we will create one large Page component and create a series of display components to handle each section of our portfolio.  Let's break this down:

  • This is our home page and where all of our components will be loaded and used to display portfolio info.
  • This will be our projects section that will take project data and display information about each project.  This will take a prop composed of our portfolio projects and iterate over them to display data when appropriate.
  • This will a section highlighting our skills and the types of services / work we offer to people that might peruse our portfolios.
  • This will be a section that talks about us, displaying any personal data we want to share.
  • Finally we have a component that we will use for displaying a contact form that will let users email us if they have any inquires.

2.1 The Home Page

This is our main component that act as our entry point for our portfolio.  Its job is to make several Graphql API requests for our portfolio data from Cosmic and pass that data onto the different sections of our portfolio.  Let's look at the component and talk about what's happening:

The important parts of this The only display element that really lives here is the splash screen which gives us a little bit 

2.2 Modify the Header Component

By default Gatsby gives us a Layout component that lets us wrap each page with a Header and Footer.  We are going to add some navigation for our portfolio into the header so users can navigate to different sections of our Portfolio by clicking on a nav bar that we will import from rsuite:

These links will scroll the home page down to each section via the name properties placed on each section on our home page.

2.3 The Work Component

This component takes in our data about any services we provide, specifically a names, a short summary, and a more in depth description, and let's us display that to our users:

This iterates through our services objects.  For every service that exists we add a new div to the work component section. Now we can modify and add data to our services on Cosmic and it will update accordingly.

2.4 The Projects and About Components

These sections will behave in essentially the  same way,  we display some information from our "Home Page".  Just a bit of text to give the user some context for each section, but after that we just iterating through our list objects we have saved to our Cosmic bucket:

And just like Project displays a heading and display images and data about projects, we can do the same with the individuals and data in the about section:

2.5 The Contact Component

Lastly we have a component that will users to contact us at an email we specify.  This will handle our contact form, and will be initialized with some state variables so we can control our user inputs, all the input and form components are handled by rsuite so we don't have to add too many styling properties to our form fields and feedback components:

Essentially we Validate our form fields and check if all the form fields are present, then we a the mailto url to open an email client and populate it with our message.

3.0 Deployment (optional)

Now we are ready to deploy our app.  The most important part of this process is making sure that our app rebuilds itself when we change any data on Cosmic.  If we integrate continuous deployment using git Netlify will allow us to activate a buildhook in order to generate new static files using updated data fetched from the Cosmic API.

3.1 Deploying from Git

Go to Netlify and create an account if you don't aready have one.  From the apps dashboard click New Site from Git at the app dahsboard.  From there you will be walked through the process of authorizing Netflify to access a repository from a git service (github, gitlab, bitbucket).

You will have to add you COSMIC_READ_KEY and your COSMIC_BUCKET_SLUG as environment variables. This can be found under the deploy settings once the app has been created on Netlify.  In the same area you can create your buildhook to allow Cosmic to request a rebuild of your files once an update is made:

Once the build hooks is created go over to Cosmic and add it to the webhooks tab under the settings for your bucket:

Follow the instructions for webhooks to fire a post request to that url every time an object is updated and you should have a continuously deployed, super fast portfolio site ready to be updated.

Thanks for following along with me and I'll see you next time I decide to build something cool :)