Overview

Here you will have an overview of the philosophy of the library and a common workflow for your queries.

The TSGhostContentAPI object is your entry-point, it will contains all the available endpoints and need to be instantiated with your Ghost Blog API Credentials, the URL, and the Content API Key.

import { TSGhostContentAPI } from "@ts-ghost/content-api";
 
const api = new TSGhostContentAPI("https://demo.ghost.io", "22444f78447824223cefc48062", "v5.0");

From this api instance you will be able to call any resource available in the Ghost Content API and have the available methods exposed.

Available resource

Resource.read().browse()
api.posts✅✅
api.pages✅✅
api.authors✅✅
api.tiers✅✅
api.tags✅✅
api.settings**
  • settings resource only has a fetch function exposed, no query builder.

Building Queries

Calling any resource like authors, posts, etc (except settings resource) will give a new instance of APIComposer containing two exposed methods read and browse (if you are interested in a version that exposes add, edit and delete you will have to check the @ts-ghost/admin-api).

This instance is already built with the associated Schema for that resource so any operation you will do from that point will be typed against the asociated schema. Since you are using TypeScript you will get a nice developer experience with autocompletion and squiggly lines if you try to use a field that doesn't exist on the resource.

browse and read methods accept an options object. These params mimic the way Ghost API Content is built but with the power of Zod and TypeScript they are type-safe here.

let query = api.posts.browse({
  limit: 5,
  order: "title DESC",
  //      ^? the text here will throw a TypeScript lint error if you use unknown field.
});

(Optional) Altering the output

After calling read or browse you get a Fetcher instance that you can use to optionnaly alter the output of the result.

For example if we want to fetch only the id, slug and title of our blog posts we could do:

let query = api.posts
  .browse({
    limit: 5,
    order: "title DESC",
  })
  .fields({
    id: true,
    slug: true,
    title: true,
  });

Fetching the data

After building your query and optionnaly using output formatting, you can fetch it with the async fetch method. This method will return a Promise that will resolve to a result object that was parsed by the Zod Schema of the resource.

let query = await api.posts
  .browse({
    limit: 5,
    order: "title DESC",
  })
  .fields({
    id: true,
    slug: true,
    title: true,
  })
  .fetch();
 
// or without fields selection
 
let query2 = await api.posts
  .browse({
    limit: 5,
    order: "title DESC",
  })
  .fetch();

Alternatively, coming from a browse query you also have access to the paginate method, instead of fetch. This version will return a cursor and a next fetcher to directly have the next query with the same parameters but on page n + 1. See a complete example in the Common Recipes section.

The result is a discriminated union with the Boolean success as a discriminator, so a check on success will let you know if the query was successful or not. The shape of the "OK" path depends on the query you made and the output modifiers you used.

const result: {
    success: true;
    data: Post; // Shape depends on resource + browse | read + output modifiers
    // contains aditionnal metadata for browse queries
} | {
    success: false;
    errors: {
        message: string;
        type: string;
    }[];
}