@janbox/contentful-marketplace-sdk
v2.0.1
Published
TypeScript SDK for querying iChiba marketplace content from Contentful GraphQL.
Readme
@janbox/contentful-marketplace-sdk
TypeScript SDK for querying iChiba marketplace content from Contentful GraphQL.
Features
- Typed API for marketplace content entries.
- Built-in market/language filtering in query builders.
- Single-entry methods with 404 handling.
- Works in both ESM and CJS builds.
Installation
# pnpm
pnpm add @janbox/contentful-marketplace-sdk
# npm
npm install @janbox/contentful-marketplace-sdk
# yarn
yarn add @janbox/contentful-marketplace-sdkQuick Start
import {
ContentfulSDK,
getBannerCollections,
} from "@janbox/contentful-marketplace-sdk";
ContentfulSDK.configure({
url: `https://graphql.contentful.com/content/v1/spaces/${process.env.CONTENTFUL_SPACE_ID}/environments/master`,
headers: {
Authorization: `Bearer ${process.env.CONTENTFUL_ACCESS_TOKEN}`,
},
});
const result = await getBannerCollections({
slot: "home_hero",
marketCode: "vn",
language: "en",
platform: "WEB",
page: 1,
size: 10,
});
console.log(result.items);Configuration
ContentfulSDK.configure(params)
Configure the SDK once before calling entry methods.
| Parameter | Type | Required | Description |
|-----------|--------------------------|----------|-------------------------------------------|
| url | string | ✅ | GraphQL endpoint URL |
| method | string | — | HTTP method (defaults to "POST") |
| headers | Record<string, string> | — | Custom headers (e.g. Authorization) |
ContentfulSDK.configure({
url: "https://graphql.contentful.com/content/v1/spaces/your-space-id/environments/master",
headers: {
Authorization: "Bearer your-delivery-access-token",
},
});Notes:
- The SDK always sends
Content-Type: application/json. Custom headers are merged on top. - Runtime requires
fetch(Node.js 18+ recommended).
API Methods
Collection methods return { page, total, size, items }.
Detail methods return the entry object directly.
Banner Collection
getBannerCollections(options)
await getBannerCollections({
slot: "home_hero",
page: 1,
size: 20,
platform: "WEB",
marketCode: "vn",
language: "en",
});Blog
getBlogPosts(options?)getBlogPostDetail({ id } | { slug })
const posts = await getBlogPosts({
marketCode: "vn",
language: "en",
page: 1,
size: 10,
});
// paging response shape: { page, total, size, items }
const post = await getBlogPostDetail({
slug: "how-to-shop-online",
marketCode: "vn",
language: "en",
});
const postById = await getBlogPostDetail({
id: "1a2b3c4d5e",
marketCode: "vn",
language: "en",
});Documentation
getDocCategories(options?)getDocCategoryDetail({ id } | { slug })getDocArticles(options?)getDocArticleDetail({ id } | { slug })
const categories = await getDocCategories({
marketCode: "vn",
language: "en",
page: 1,
size: 10,
});
// paging response shape: { page, total, size, items }
const category = await getDocCategoryDetail({
slug: "getting-started",
marketCode: "vn",
language: "en",
});
const categoryById = await getDocCategoryDetail({
id: "1a2b3c4d5e",
marketCode: "vn",
language: "en",
});
const articles = await getDocArticles({
categorySlug: "getting-started",
marketCode: "vn",
language: "en",
page: 1,
size: 10,
});
// getDocArticles returns summary fields only (no content, no seo)
const article = await getDocArticleDetail({
slug: "payment-methods",
marketCode: "vn",
language: "en",
});
const articleById = await getDocArticleDetail({
id: "1a2b3c4d5e",
marketCode: "vn",
language: "en",
});Brand / Hyperlink / Keyword Collections
getBrandCollections(options?)getHyperlinkCollections(options?)getKeywordCollections(options?)
const brands = await getBrandCollections({
marketCode: "vn",
language: "en",
page: 1,
size: 20,
});
const links = await getHyperlinkCollections({
page: 1,
size: 20,
marketCode: "vn",
language: "en",
});
const keywords = await getKeywordCollections({
marketCode: "vn",
language: "en",
page: 1,
size: 20,
});Policy and Terms
getPolicyAndTerms(options?)— returns a single entry (limit: 1), throws404if not found
const policy = await getPolicyAndTerms({
marketCode: "vn",
locale: "vi",
});
// policy shape: { sys: { id }, title, locale, content: { json, links } | null }Filters marketCode / locale with global fallback (entries where markets / locale is not set are included).
Error Handling
getBlogPostDetail, getDocCategoryDetail, and getDocArticleDetail throw:
Error("Either id or slug is required.")if neitheridnorslugis provided.Responsewith status404when no entry is found.
try {
await getDocArticleDetail({ slug: "unknown-slug" });
} catch (error) {
if (error instanceof Response && error.status === 404) {
console.log("Entry not found");
}
}Market/Language Filtering Behavior
When marketCode or language is provided, queries include both:
- entries matching the given code
- entries where that field is not set
This supports global fallback content.
Exported Types
The package exports:
- client and entry functions from
src/clientandsrc/entries - Contentful schema types from
src/types - entry aliases such as
BlogPostEntry,DocArticleEntry, andDocCategoryEntry
Development
From repository root:
pnpm install
pnpm --filter @janbox/contentful-marketplace-sdk build
pnpm --filter @janbox/contentful-marketplace-sdk test