By Paul Scanlon

Using Gatsby Serverless Functions as an abstracted API

They’re here! Gatsby Serverless Functions are here! They’re finally here! 💝 — And I couldn’t be more excited!

A little while ago I wrote a post about using the Twitter API as a kind of CMS for my blog. You can read more about that here: Use Netlify Functions and the Twitter API v2 as a CMS for your Gatsby blog

In short I created my own mini API that is used by both my commercial portfolio: and my blog: to display my current Twitter bio information on the home page(s).

Both my sites are built on top of my Gatsby theme gatsby-theme-terminal which I haven’t updated to Gatsby v3.x.x yet, and both sites are currently hosted by Netlify… but I didn’t want that to hold me up from adopting Gatsby Serverless Functions.

Here’s how I did it. 👇


My API is actually a very simple Gatsby Site deployed on Gatsby Cloud. It displays the response from my endpoints in HTML <pre> tags. This isn’t entirely necessary but it allows me to test a request and preview the responses in an almost real and un-abstracted way.

You can also see the json response for each of my endpoints using the links below:


To use Gatsby Serverless Functions have a read of the Getting Started docs but i’ll break down the steps you’ll probably need to use Gatsby Serverless Functions anyway

Install Dependencies

You’ll need Gatsby 3.4.0 or higher installed

npm install gatsby@latest

Enable Feature Flag

Gatsby Serverless Functions are still technically in beta so you’ll need to add FUNCTIONS as a feature flag in your gatsby-config.js

// gatsby-config.js

module.exports = {
  flags: {
    FUNCTIONS: true
  plugins: [...]

🚨 News just in from Joel Sumner Smith | Product Manager @Gatsby👇

File System - API

Like with the File System Route API The path to Functions is the same on disk as it would be in browser: E.g src/api/some-function => http(s)://.../api/some-function


I have x2 two endpoints in my API they both work in the same way but here’s the twitter-user endpoint

// api/twitter-user.js

const { twitter } = require('../clients'); // exports Twitter client

export default async function handler(req, res) {
  res.setHeader('Access-Control-Allow-Origin', '*'); // YOLO
  try {
    const { data } = await twitter.get('users/by/username/PaulieScanlon', {
      user: {
      user: data,
  } catch {
      error: 'Ooops server error',


I use fetch to hit my API and set the response in state which is then returned by Jsx.

I fetch the data in the ProfileInfo.js component in both my blog and my site

// Any React component


  const [twitter, setTwitter] = useState({ user: null })

  useEffect(() => {
      .then((response) => {
        if (response.status >= 200 && response.status <= 299) {
          return response.json()
        } else {
          throw Error(response.message)
      .then((response) => {
        // Save response in state hook
      .catch((error) => {
        // Handle the error
  }, [])

  return (
      {twitter.user ? (
          <h2>Twitter User</h2>
            <code>{JSON.stringify(twitter.user, null, 2)}</code>
      ) : null}


… and that’s pretty much it. I might at some point do something with the GitHub data but I just wanted to share how i’m using Gatsby Serverless Functions in an abstracted and potentially easily incrementally adoptable way. — jeez what a sentence! 🕺


Leave a reaction and let me know how I'm doing.

  • 0
  • 0
  • 0
  • 0
  • 0
Powered byNeon