@flowup/contentful-client
TypeScript icon, indicating that this package has built-in type declarations

3.0.0 • Public • Published

@flowup/contentful-client

This package provides a type-safe wrapper for Typescript around the Contentful client from the contentful package.

It is recommended to use this with the @flowup/contentful-types-generator, which enables generating Contentful types automatically instead of writing them manually.

For more information on querying Contentful, see documentation on the Content Delivery API.

Installation

npm install @flowup/contentful-client

Usage

Setup

Create a ContentfulClient instance, supplying necessary configuration for your Contentful space.

To make use of type-checking and IDE intelisense, create types for your Contentful space and the content types contained therein, and supply it as a generic type.

For example:

import { ContentfulClient, ContentfulConfig } from '@flowup/contentful-client';
import { Entry } from 'contentful';

// map Contentful content type ID to content model
interface SpaceModel {
  author: AuthorModel;
  book: BookModel;
}

// map Contentful field ID to type
interface AuthorModel {
  name: string;
  age: number;
  rating?: number;
}
interface BookModel {
  title: string;
  author: Entry<AuthorModel>; // link to another content type
}

// configure Contentful environment
const config: ContentfulConfig = {
  spaceId: '...',
  accessToken: '...',
  environment: '...',
  // ...
};

// create connection to Contentful
const client = new ContentfulClient<SpaceModel>(config);

Setup with types generator

Since creating and maintaining the Contentful types can be cumbersome and error-prone, it is recommended to automate this process. See @flowup/contentful-types-generator package for instructions on how to generate the types via CLI. Once the types are generated, all that is needed is to supply the Contentful space type, e.g.:

import { ContentfulClient } from '@flowup/contentful-client';
import { AppSpace } from './app-space.ts';

const client = new ContentfulClient<AppSpace>({
  // ...
});

Querying

Single-line comments show inferred types.

Ordering

Example of ordering:

/* fetch top 10 highest rated authors */
client
  .getFields({
    contentType: 'author', // keyof SpaceModel
    ordering: {
      field: 'rating', // keyof AuthorModel
      desc: true,
    },
    limit: 10,
  })
  // Promise<AuthorModel[]>
  .then(authors => {
    console.log(authors);
  });

Example of ordering by metadata field:

/* fetch 5 most recent books */
client
  .getFields({
    contentType: 'book', // keyof SpaceModel
    ordering: {
      metadata: 'createdAt',
      desc: true,
    },
    limit: 5,
  })
  // Promise<BookModel[]>
  .then(books => {
    console.log(books);
  });

Example of ordering by multiple fields:

/* fetch top 10 authors - if they have the same rating, order from youngest */
client
  .getFields({
    contentType: 'author', // keyof SpaceModel
    ordering: [
      {
        field: 'rating', // keyof AuthorModel
        desc: true,
      },
      {
        field: 'age', // keyof AuthorModel
        desc: false /* ascending is default */,
      },
    ],
    limit: 10,
  })
  // Promise<AuthorModel[]>
  .then(authors => {
    console.log(authors);
  });

Filtering

Example of filtering by fields:

/* filter books for exact title match */
client
  .getFields({
    contentType: 'book', // keyof SpaceModel
    filters: {
      fields: {
        // keyof BookModel
        title: {
          value: 'The Shining', // string
        },
      },
    },
    limit: 1,
  })
  // Promise<BookModel[]>
  .then(books => {
    if (books.length === 0) {
      console.log('Book not found');
    } else {
      console.log(
        `${books[0].title} is written by ${books[0].author.fields.name}`,
      );
    }
  });

Example of filtering by metadata:

/* filter books created since a certain date */
client
  .getItems({
    contentType: 'book', // keyof SpaceModel
    filters: {
      metadata: {
        createdAt: {
          operator: 'gte',
          value: '2020-01-01',
        },
      },
    },
  })
  // Promise<Entry<BookModel[]>>
  .then(bookEntries => {
    bookEntries.forEach(bookEntry => {
      console.log(
        `${bookEntry.fields.title} was created at ${bookEntry.sys.createdAt}`,
      );
    });
  });

Example of filtering by sub-fields:

/* filter books whose author is younger than 21 */
client
  .getFields({
    contentType: 'book', // keyof SpaceModel
    filters: {
      subfields: {
        // keyof BookModel
        author: {
          contentType: 'author', // 'author'
          fields: {
            // keyof AuthorModel
            age: {
              operator: 'lt',
              value: 21, // number
            },
          },
        },
      },
    },
  })
  // Promise<BookModel[]>
  .then(books => {
    books.forEach(book => {
      console.log(
        `Author of ${book.title} is ${book.author.fields.age} years old`,
      );
    });
  });

Selection

Example of selecting specific fields and metadata:

/* fetch names of authors */
client
  .getFields({
    contentType: 'author', // keyof SpaceModel
    select: {
      fields: ['name', 'age'], // (keyof AuthorModel)[]
      metadata: ['id'], // (keyof Sys)[]
    },
  })
  // Promise<AuthorModel[]>
  .then(authors => {
    console.log(authors);
  });

Example of selecting only content fields (without sys metadata):

/* fetch names of authors */
client
  .getFields({
    contentType: 'author', // keyof SpaceModel
    select: 'fields',
  })
  // Promise<AuthorModel[]>
  .then(authors => {
    console.log(authors);
  });

Versions

Current Tags

  • Version
    Downloads (Last 7 Days)
    • Tag
  • 3.0.0
    0
    • latest

Version History

Package Sidebar

Install

npm i @flowup/contentful-client

Weekly Downloads

0

Version

3.0.0

License

ISC

Unpacked Size

27 kB

Total Files

6

Last publish

Collaborators

  • helloflowup
  • paveltobias
  • vmasek
  • mrkpks
  • matejchalk
  • siso