Services
strapi2front generates type-safe service functions for all your content types. These services handle API communication with your Strapi backend.
Service Structure
Section titled “Service Structure”Each content type gets a service with these methods:
export const articleService = { findMany, // List with filters, returns { data, pagination } findAll, // Fetch ALL entries (handles pagination automatically) findOne, // Get by documentId create, // Create new entry update, // Update existing entry delete, // Delete entry};findMany (Paginated List)
Section titled “findMany (Paginated List)”Retrieve multiple entries with optional filters, pagination, and sorting. Returns paginated response with data and pagination metadata.
import { articleService } from "@/strapi/collections/article/service";
// Get first page of articlesconst { data: articles, pagination } = await articleService.findMany();
// With paginationconst { data: page1, pagination } = await articleService.findMany({ pagination: { page: 1, pageSize: 10 },});
// With filtersconst { data: published } = await articleService.findMany({ filters: { publishedAt: { $notNull: true }, title: { $contains: "TypeScript" }, },});
// With sortingconst { data: latest } = await articleService.findMany({ sort: ["publishedAt:desc", "title:asc"],});
// With relations (populate)const { data: withAuthor } = await articleService.findMany({ populate: ["author", "categories"],});
// Complex populateconst { data: detailed } = await articleService.findMany({ populate: { author: { fields: ["name", "email"] }, categories: { populate: ["icon"] }, },});findAll (All Entries)
Section titled “findAll (All Entries)”Fetch ALL entries automatically handling pagination. Useful when you need every item.
// Get ALL articles (handles pagination internally)const allArticles = await articleService.findAll();
// With filters - gets all matching itemsconst allPublished = await articleService.findAll({ filters: { publishedAt: { $notNull: true } },});
// With relationsconst allWithAuthors = await articleService.findAll({ populate: ["author"],});findOne
Section titled “findOne”Get a single entry by its documentId.
import { articleService } from "@/strapi/collections/article/service";
// Get by documentIdconst article = await articleService.findOne("abc123xyz");
// With specific fieldsconst article = await articleService.findOne("abc123xyz", { fields: ["title", "content"],});
// With relationsconst article = await articleService.findOne("abc123xyz", { populate: ["author", "categories"],});create
Section titled “create”Create a new entry.
import { articleService } from "@/strapi/collections/article/service";
const newArticle = await articleService.create({ title: "My New Article", slug: "my-new-article", content: "Article content here...",});
// With relationsconst articleWithAuthor = await articleService.create({ title: "New Article", content: "Content...", author: "authorDocumentId", categories: ["cat1", "cat2"],});
// With draft status (Strapi v5)const draft = await articleService.create( { title: "Draft Article", content: "..." }, { status: "draft" });update
Section titled “update”Update an existing entry.
import { articleService } from "@/strapi/collections/article/service";
const updated = await articleService.update("abc123xyz", { title: "Updated Title",});
// Partial updates (only changed fields)const updated = await articleService.update("abc123xyz", { content: "New content only",});
// Update with status changeconst published = await articleService.update( "abc123xyz", { title: "Final Title" }, { status: "published" });delete
Section titled “delete”Delete an entry.
import { articleService } from "@/strapi/collections/article/service";
await articleService.delete("abc123xyz");Filtering
Section titled “Filtering”Strapi supports powerful filtering operators:
const { data: filtered } = await articleService.findMany({ filters: { // Equality status: "published",
// Comparison views: { $gt: 100 }, rating: { $gte: 4 }, stock: { $lt: 10 }, price: { $lte: 99.99 },
// String matching title: { $contains: "guide" }, slug: { $startsWith: "how-to" }, email: { $endsWith: "@example.com" },
// Null checks publishedAt: { $notNull: true }, deletedAt: { $null: true },
// Array membership category: { $in: ["tech", "science"] }, status: { $notIn: ["draft", "archived"] },
// Logical operators $or: [ { status: "published" }, { featured: true }, ], $and: [ { views: { $gt: 100 } }, { rating: { $gte: 4 } }, ], },});Population (Relations)
Section titled “Population (Relations)”Control which relations are loaded:
// Array of relation namesconst { data: articles } = await articleService.findMany({ populate: ["author", "categories"],});// Nested populationconst { data: articles } = await articleService.findMany({ populate: { author: { populate: ["avatar", "socialLinks"], }, categories: { fields: ["name", "slug"], }, },});// Deep population with filtersconst { data: articles } = await articleService.findMany({ populate: { comments: { filters: { approved: true }, sort: ["createdAt:desc"], populate: { author: { fields: ["name"], }, }, }, },});Localization (i18n)
Section titled “Localization (i18n)”For content types with i18n enabled:
// Get content in specific localeconst { data: spanishArticles } = await articleService.findMany({ locale: "es",});
// Get all localizationsconst article = await articleService.findOne("abc123", { populate: ["localizations"],});Draft & Publish
Section titled “Draft & Publish”For content types with draft/publish enabled:
// Get only published (default)const { data: published } = await articleService.findMany({ status: "published",});
// Get draftsconst { data: drafts } = await articleService.findMany({ status: "draft",});
// Create as draftconst draft = await articleService.create( { title: "Work in Progress" }, { status: "draft" });
// Publish a draftconst published = await articleService.update( "abc123", {}, { status: "published" });Error Handling
Section titled “Error Handling”Services throw errors for failed requests:
try { const article = await articleService.findOne("invalid-id");} catch (error) { if (error.status === 404) { console.log("Article not found"); } else { console.error("API error:", error.message); }}Client Configuration
Section titled “Client Configuration”Services use a shared client configured with your Strapi URL and token from environment variables.
User Authentication (Beta)
Section titled “User Authentication (Beta)”By default, services use STRAPI_TOKEN from your environment. For user-authenticated requests (e.g., after login), you can pass clientOptions to any service method:
import { articleService } from "@/strapi/collections/article/service";
// Default: uses STRAPI_TOKENawait articleService.findMany();
// With user JWT tokenawait articleService.findMany( { filters: { author: userId } }, { authToken: session.jwt });
// Create as authenticated userawait articleService.create( { title: "My Post", content: "..." }, { authToken: userJwt });
// Update with user tokenawait articleService.update( "abc123", { title: "Updated" }, { authToken: userJwt });
// Delete with user tokenawait articleService.delete("abc123", { authToken: userJwt });ClientOptions
Section titled “ClientOptions”All service methods accept an optional clientOptions parameter:
interface ClientOptions { /** JWT token or API token for authentication */ authToken?: string; /** Base URL of the Strapi instance (for multi-tenant setups) */ baseURL?: string;}Creating a Reusable Client
Section titled “Creating a Reusable Client”For multiple operations with the same token, create a client instance:
import { createStrapiClient } from "@/strapi/shared/client";
// Create client with user tokenconst userClient = createStrapiClient({ authToken: session.jwt });
// Use the client directlyconst articles = await userClient.collection("articles").find();const homepage = await userClient.single("homepage").find();Multi-tenant Setup
Section titled “Multi-tenant Setup”For applications connecting to different Strapi instances:
// Connect to a different Strapi instanceawait articleService.find( {}, { baseURL: "https://tenant-a.strapi.example.com", authToken: tenantToken, });