Introduction

We all know it's a pain to keep static portfolio sites updated -- copy/pasting content, managing layout, rebuilding and redeploying, etc.

illustrative tweet

What if your developer portfolio website updated automatically along with your content? Beyond that, what if you could generate your portfolio site with no code involved?

Using a pre-built GraphQL API

Let me show you how I made this dynamic, no-code portfolio solution using a GraphQL API I assembled in the StepZen GraphQL Studio!

screenshot of studio

The StepZen GraphQL Studio lets you explore single or combination GraphQL schemas and their queries for popular APIs - no StepZen account needed. (However, I do recommend signing up for a StepZen account -- it makes key management a breeze in the long run.)

For my project I chose a combination - the Developer Publishing Pack - which includes the three APIs I need to power my portfolio site: Dev-to, GitHub, and Twitter.

Looking at the overall project map

First off, let's zoom out and take a look at the overall design of my portfolio site.

screenshot of sketched-out graph

Note: The original static structure of the project and the logic surrounding env variables comes from a blog post by Cassidy Williams.

There's a template repository, which is deployed to a new instance via the Netlify click to deploy button. As you can see, the final values in the site are determined by entries in a form in the generator, and these values remain static.

So we've got the generator with this version of the design, but every time that you have a new portfolio project featured on GitHub, you'd have to either a) edit your custom site instance or b) generate a whole new version of the site.

Making the site dynamic

How do we make the deployed site dynamic, so that you don't have to worry about editing the site when you make a new project?

This is where the endpoint from StepZen's GraphQL Studio comes in!

second screenshot of sketched-out graph

I made the template here using NextJS, because Netlify has a NextJS plugin, which automates the process of using serverless functions. I inserted the call to my StepZen GraphQL endpoint in the pages/api folder to keep sensitive info off the client.

I created the generator site in AlpineJS, as the only capabilities in the generator that I needed were capturing values from the client and dynamically inserting them in the Deploy to Netlify button.

Here's the key bit of information: Because each custom site instance now includes a call to my StepZen endpoint, the information returned can be dynamic. Specifically, my endpoint connects the GitHub, Twitter, and DEV.to APIs and returns the top posts from DEV.to as ell as the current pinned tweet and GitHub repositories.

This means that to keep your site updated with content, all you have to do is change your pins on Twitter or GitHub, and sit and watch your top stats change on DEV.to!

Generating the GraphQL endpoint

I started by selecting the Developer Publishing Pack combination in the StepZen GraphQL Studio.

screenshot of studio

Next, I played around with the APIs and queries using mock data until I found a query that returned top DEV.to posts along with Twitter and GitHub pins.

second screenshot of studio

Here's that query.

query MyQuery ($github_token: Secret! $twitter_bearerToken: Secret!, $username: String!) {
  devto_getArticles(username: $username, top: 3) {
    title
    published_at
    user {
      github_details(github_token: $github_token) {
        pinnedItems(first: 3) {
          nodes {
            ... on Github_Repository {
              id
              name
              description
            }
          }
        }
      }
      twitter_details(
        twitter_bearerToken: $twitter_bearerToken
      ) {
        pinned_tweet(
          twitter_bearerToken: $twitter_bearerToken
        ) {
          text
        }
      }
      github_username
      username
      twitter_username
    }
  }
}

The GraphQL Studio allows us to access the endpoint we've assembled and use it in my application.

Here, I clicked Publish in the GraphQL Studio to reveal the endpoint I had assembled and copied it:

screenshot of publishing button

Consuming the GraphQL endpoint

After creating the GraphQL endpoint in the Studio you can send a request to it from a frontend application. Alternatively, you could also download your schema and sign up for a StepZen account, to make key management easier.

From a new file in the pages/api directory in a Next.js project you can add a simple fetch request to interact with the GraphQL endpoint:

const response = await fetch(
  "https://graphql1f.steprz.net/api/1fec739d90f6028c74a6f19855c34277/__graphql", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: INSERT_QUERY_BODY_HERE,
    variables: {
      github_token: github_token,
      twitter_bearerToken: twitter_bearerToken,
      username: username,
    }
  }
)

The values for the variables object in the fetch requested are retrieved from the environment variables. These variables are set when you enter the values in the generator.

screenshot of form

These variables then give you access to the GitHub and Twitter APIs (the information retrieved from the DEV.to API does not require a key to access).

Hit 'Deploy to Netlify', follow Netlify's instructions, and there you go!

screenshot of template site

Conclusion

We covered the overall design of our custom dynamic portfolio site solution, as well as how I created the endpoint that gave the site its dynamic quality by calling an endpoint I created in the StepZen GraphQL Studio.

We also took a look at how I consumed that endpoint on the frontend.

There are a lot of pre-built API combinations available in the GraphQL Studio, including:

  • Google Maps + Yelp Reviews
  • Outdoor Dining Search
  • Social Media Sentiment Analysis

Or you could make your own!

I'm curious to hear about your ideas for a dynamic site generator. Would you create a generator that makes dynamically updated image collages based on the user's input? Or perhaps a generator that creates a review widget for a chain of restaurants, depending on which chain you use in the environment variables? We'd love to hear your ideas! Jump into our Discord channel anytime.