This post is written by Joe Ashwell, who runs a few online businesses mentioned below. Joe has been a blogstatic customer for quite some time and utilizes the blogstatic non-Auth JSON API to render his blogs on his end. Below is his detailed approach with code examples.


I've been a huge fan of V and blogstatic for a few years now and have been using it for a number of projects, including: BOXCUT, MineWork - a job board for the mining industry, and most recently UnwindHR an HR tool for small teams.

I love the simplicity of it, the super clean UI, direct fast support from the founder, its stability, and ultimately how affordable it is. The fact you can whip up a hosted blog for US$19/year (yeah, a year) is insanely good value!

I wanted full control of the styling, and ultimately to host on the same domain as my app. So, I use the API provided from blogstatic to render the posts within my nextjs projects.

Incredibly simple and straightforward!

Fetch All Posts

For the /blog/page.tsx page, just simply fetch all your blog posts using your provided API key (you can find this within your blogstatic dashboard → Dashboard > Settings > API).

const fetchAllBlogPosts = async () => {
  const requestURL = `https://api.blogstatic.io/${process.env.BLOGSTATIC_API_KEY}/posts.json`;
  const response = await fetch(requestURL);
  const allPostData = await response.json();
  return allPostData;
};

For the categories, it's effectively the exact same process.

const fetchAllCategories = async () => {
  const requestURL = `https://api.blogstatic.io/${process.env.BLOGSTATIC_API_KEY}/categories.json`;
  const response = await fetch(requestURL);
  const allCatData = await response.json();
  return allCatData;
};

Then simply just render all the previews for the blog posts onto the page.

const Blog = async ({ params }: { params: { slug: string } }) => {
  const posts = await fetchAllBlogPosts();
  const { slug } = params;
  return (
    <div className="flex flex-col max-w-[1500px] mx-auto p-4 mt-8 md:mt-0 lg:p-16">
      <BlogHeader slug={slug} posts={posts} />
      <CategoriesHeader slug={slug} />
      <div className="flex w-full flex-wrap items-start justify-start mt-8 lg:mt-16">
        {posts.map((post: BlogPostType) => (
          <BlogGridItem key={post.post_url} post={post} />
        ))}
      </div>
    </div>
  );
};

Fetch Individual Posts

Then for the individual blog post page - in my case, it's the /blog/[slug]/page.tsx. You can follow the exact same process as above, but use a slightly different function to fetch the individual post, which has much more post info provided and returned on it.

const fetchPost = async (slug: string) => {
  const requestURL = `https://api.blogstatic.io/${process.env.BLOGSTATIC_API_KEY}/${slug}.json`;
  const response = await fetch(requestURL, { next: { revalidate: 60 } });
  const postData = await response.json();
  return {
    postData,
  };
};

Then you simply render the page. The API is so good, it even returns related posts which really helps with internal linking across each of the blog posts.

<div className="flex flex-col my-4">
  {postData?.related_posts?.map((post: BlogPostType) => (
    <div key={post.id} className="my-1">
      <link classname="text-blue-600 hover:underline" href="{`/blog/${post.post_url}`}">
        {post.post_title}
      </Link>
    </div>
  ))}
</div>

The combination of nextjs + blogstatic is absolutely perfect for me.

There's literally zero maintenance required, and the best thing is these blog posts are built on the server at build time, so it's perfect for SEO! Whenever you want to include a new blog post, just redeploy your app to update the sitemap, etc. 🤙

Create Your Blog

The quickest way to create your new blog!

Learn More

Found in:

Customer Series