Display Hubspot blogs in Gatsby site

Highlighted
Regular Contributor

Hi

 

I will soon be working on a Gatsby site powered by react.js which will need to pull in and display Hubspot blogs.

 

I see on the Gatsby site there is a plugin but out of curiosity has anyone here done anything like this and is there is anything to consider or watch out for?

 

Any information much appreciated 

5 Replies 5
Highlighted
HubSpot Alumni

Hi @Jools619,

 

So I haven't worked with Gatsby at all, but I think I found the documentation for the plugin you're referring to: https://www.gatsbyjs.org/packages/gatsby-source-hubspot/?=hubspot. It sounds like you basically plug in your HubSpot account's API key. And then the options from the plugin look to be the same as what's in our API: https://developers.hubspot.com/docs/methods/blogv2/get_blog_posts. You can fiter the response based on the options in that documentation.

 

I don't have much in the way of things to keep in mind, since I haven't actually used the plugin. But I would imagine it's pretty much the same as making requests directly to our API. So if you have any questions about making your requests, feel free to reply here.

 

 - Leland

Leland Scanlan

HubSpot Developer Support
Reply
0 Upvotes
Occasional Contributor

I haven't gotten the actual content of a page in a template yet, but this is far as I've gotten:

 

in gatsby-node.js

 

const axios = require('axios');

exports.createPages = async ({actions}) => {
  const response = await axios({
    method: 'get',
    url:
      'https://api.hubapi.com/content/api/v2/blog-posts?hapikey=<your-api-key>',
    responseType: 'json',
    cors: 'no-cors'
  });

  const posts = response.data.objects;

  posts.forEach(post => {
    const newSlug = post.slug.replace('/blog', '');
    actions.createPage({
      path: `/${post.slug}`,
      component: require.resolve('./src/templates/post.js'),
      context: {
        slug: newSlug
      }
    });
  });
};

You might not need this line:

const newSlug = post.slug.replace('/blog', '');

and then in src/templates/post.js

import React from 'react';
import {graphql} from 'gatsby';
import PropTypes from 'prop-types';
import Header from '../components/Header';
import Footer from '../components/Footer';

export const query = graphql`
  query($path: String!) {
    allSitePage(filter: {path: {eq: $path}}) {
      edges {
        node {
          path
        }
      }
    }
  }
`;

const Post = ({data}) => {
  return (
    <div>
      <Header />
      <div className="col-12 col-md-6 col-lg-5 mx-auto my-5 py-5">
        <p>{data.allSitePage.edges[0].node.path}</p>
      </div>
      <Footer />
    </div>
  );
};

Post.propTypes = {
  data: PropTypes.object
};

export default Post;

Hope that helps.

Reply
0 Upvotes
Highlighted
HubSpot Alumni

That's excellent; thank you for replying. Just tagging @Jools619 to make sure they see this.

 

Leland Scanlan

HubSpot Developer Support
Reply
0 Upvotes
Highlighted
Regular Contributor

Thanks Guys

I will refer  to this once I come to working on it 🙂

 

 

Reply
0 Upvotes
Highlighted
Occasional Contributor

Got it working - there's a gatsby-source-hubspot plugin.

 

In my gatsby-config.js

{
  resolve: 'gatsby-source-hubspot',
  options: {
    key: process.env.HUBSPOT_API_KEY
  }
},

In my gatsby-node.js

exports.createPages = async ({actions, graphql}) => {
  const result = await graphql(`
    {
      allHubspotPost {
        edges {
          node {
            id
            title
            body
            state
            author {
              id
              avatar
              name
              full_name
              bio
              slug
            }
            feature_image {
              url
              alt_text
            }
            meta {
              title
              description
            }
            summary
            published
            updated
            created
            slug
          }
        }
      }
    }
  `);

  const posts = result.data.allHubspotPost.edges.map(({node}) => node);

  posts.forEach(post => {
    console.log(post);
    actions.createPage({
      path: `/blog/${post.slug}`,
      component: require.resolve('./src/templates/post.js'),
      context: {
        slug: post.slug
      }
    });
  });
};

path, component, and context are configurable to whatever you want.

 

Then the blog posts listing page is like this

Blog.propTypes = {
  data: PropTypes.object
};

function Blog({data}) {
  const posts = data.allHubspotPost.edges.map(({node}) => node);
  console.log(posts[0]);
  return (
    <>
      <Header />
      <BlogHeader />
      <div className="container">
        <div className="row justify-content-center">
          {posts.map(post => (
            <BlogPostPreview
              key={post.id}
              title={post.title}
              slug={post.slug}
              alt={post.feature_image.alt_text}
              url={post.feature_image.url}
            />
          ))}
        </div>
      </div>
      <Footer />
    </>
  );
}

export const data = graphql`
  query {
    allHubspotPost {
      edges {
        node {
          id
          title
          feature_image {
            url
            alt_text
          }
          meta {
            title
            description
          }
          summary
          published
          updated
          created
          slug
        }
      }
    }
  }
`;

export default Blog;

Hope that helps!