Skip to main content

Introduction

Manage e-commerce products with dynamic catalogs, filtering, and search.

More information about the Catalog in the OneEntry admin panel: https://doc.oneentry.cloud/docs/category/catalog


🎯 What does this module do?

The Products module (Catalog) lets you retrieve, filter, search, and sort products in your online store or multimedia collections. You manage the catalog in the OneEntry admin panel (Catalog > Products); your app fetches products dynamically, so changing a price or attribute in the admin goes live without redeploying.

Beyond e-commerce, the Catalog also fits multimedia galleries, portfolios, document libraries, and other content collections.

🚀 Quickstart

Initialize the module from defineOneEntry:


const { Products } = defineOneEntry(
"your-project-url", {
"token": "your-app-token"
}
);

Fetch a page of products and read their fields:

// Fetch the first 20 products (empty body = no filters).
const { items, total } = await Products.getProducts([], "en_US", { limit: 20 });

console.log(`Loaded ${items.length} of ${total} products`);

items.forEach((product) => {
console.log(product.id, product.localizeInfos.title, product.price);
});

Most listing methods share the same shape: an optional filter body, a langCode, and an optional userQuery (pagination/sorting). See Parameters below for the full set.

✨ Key Concepts

What is a Product?

A product is a catalog entity (IProductsEntity) made up of:

  • Basic info - localizeInfos (title, etc.), sku, price
  • Images - product photos / gallery (stored as attributes)
  • Custom attributes - any fields you define (attributeValues): brand, material, size, color, variants, stock, …
  • Localization - per-language content

There are no fixed product types in the SDK — any structure (variants, options, downloads, bundles) is modelled with the custom attributes you configure for the catalog.

Product Organization

Products are organized through several catalog features:

  • Categories - sections of the catalog (pages of the Catalog type, created in the Pages module)
  • Product Statuses - extra filtering conditions beyond attribute filters (e.g. "in stock", "sale")
  • Product Links - connect products by attribute criteria (e.g. all black phones together)
  • Product Filters - quick search by specified filter criteria
  • Custom attributes - brand, size, color, material, …

Example hierarchy:

📁 Electronics
├─ 📱 Smartphones
│ ├─ iPhone 15 Pro
│ └─ Samsung Galaxy S24
└─ 💻 Laptops
├─ MacBook Pro
└─ Dell XPS

📁 Clothing
├─ 👕 T-Shirts
└─ 👖 Jeans

📋 What You Need to Know

Catalog architecture

Catalog categories are pages of the Catalog type created through the Pages module — create them before adding products:

  1. Open the Pages module in the admin panel.
  2. Create pages with the Catalog type — these become your product categories.
  3. Add products to those categories via Catalog > Products.

The admin Catalog also provides bulk Catalog Upload, Product Filters, Product Links, Product Statuses, and per-catalog Settings.

Pagination

Don't load everything at once — page through results with limit and offset:

Offset formula: offset = (pageNumber - 1) * limit

Default limit: you can retrieve 10 objects by default. To page through more, configure Module permissions for your needs.

Sorting

Pass sortKey and sortOrder in userQuery:

sortKeyWhat It DoesExample Use
priceSort by priceShow cheapest first
dateSort by creation dateShow newest products
titleSort alphabeticallyA-Z product list
positionCustom order (default)Hand-picked order from admin
idSort by IDTechnical sorting

Sort order: ASC (low→high) or DESC (high→low, default).

Filtering

Filtering is done through the request body (an array of IFilterParams), not userQuery. Each condition combines an attributeMarker, a conditionMarker (eq, neq, in, nin, mth, lth, exs, nexs), and a conditionValue. Combine several conditions in the array to filter by multiple criteria at once. The full condition reference is in Parameters below.


📊 Quick Reference Table - Common Methods

MethodDescriptionUse Case
getProducts()Get all products with filtering/sortingMain catalog page
getProductById()Get single product by IDProduct detail page
getProductsByPageId()Get products from category by page IDCategory page
getProductsByPageUrl()Get products from category by page URLCategory page by URL
getRelatedProductsById()Get related/similar products"You may also like" section
searchProduct()Search products by querySearch functionality
getProductsCount()Get total products countPagination info
getProductsCountByPageId()Get products count by category IDCategory pagination
getProductsCountByPageUrl()Get products count by category URLCategory pagination
getProductBlockById()Get product block by IDProduct content blocks
getProductsEmptyPage()Get products empty page structureEmpty state handling
getProductsPriceByPageUrl()Get product prices by page URLPrice filtering
getProductsByIds()Get products by a list of IDsCart, wishlist, comparison
getProductsByVectorSearch()Semantic (vector) search for productsAI-powered search

Parameters

This module accepts a set of user parameters called userQuery. If a parameter is not passed, its default is applied. Some methods also accept a body for filtering — pass an empty array (or nothing) when you don't need filters.


const userQuery = {
offset: 0,
limit: 30,
sortOrder: 'DESC',
sortKey: 'id',
signPrice: 'orders',
}

Note: the userQuery shape depends on the method. The fields above are the common base (IProductsQueryBase), used by getProducts, getProductsByPageId, getProductsByPageUrl and getProductsEmptyPage. Other methods differ: getRelatedProductsById also accepts statusMarker and templateMarker; getProductsPriceByPageUrl also accepts statusMarker (no sortKey); getProductsByIds accepts only signPrice. Filtering (attributeMarker / conditionMarker / conditionValue) is done through the request body, not userQuery — see below.

Schema

offset: number
Pagination parameter. Default 0
example: 0

limit: number
pagination parameter. Default 30
example: 30

sortKey: string
Field for sorting (default not set - sorting by position, possible values: id, title, date, price, position)
Available values: id, position, title, date, price

sortOrder: string
sorting order DESC | ASC (default DESC)
example: "DESC"

signPrice: string
Order storage marker for price fixing. If the parameter is set, the price is fixed for a certain time (see the Fixing the price section below).
example: "orders"

Method-specific fields: statusMarker (getRelatedProductsById, getProductsPriceByPageUrl) and templateMarker (getRelatedProductsById) — string | null, default null.

Use conditions to find specific products data:

attributeMarker: The text identifier of the indexed attribute by which values are filtered. conditionMarker: The type of condition to apply to the attribute value.

MarkerMeaningExample
eqEqualstatusId = 1 (active only)
neqNot equalcategory ≠ "archived"
inContains (one of)category in ["electronics", "books"]
ninNot containsbrand not in ["fake_brand"]
mthGreater thanprice > 100
lthLess thanstock < 10
exsExists (has value)Has description
nexsDoes not existNo image

conditionValue: The value to compare against.


Fixing the price (signPrice)

When you fetch products you can pass an optional signPrice parameter inside userQuery (it is also an argument on the recommendation methods of the Blocks module). It accepts the marker of an order storage and asks the server to lock the returned price for a limited time.

signPrice — type string

Order storage marker for price fixing. If the parameter is set, the price is fixed for a certain time.

Why use it. Prices can change while a customer is shopping — a discount starts, or an admin edits the price. signPrice guarantees that the price shown in the catalog or cart is exactly the price charged at checkout, so it can't drift between browsing and ordering.

How it works:

  1. Fetch products with signPrice set to your order storage marker (for example "orders").
  2. Every returned product now carries a signedPrice field — a signed token that encodes the locked price.
  3. Send that signedPrice token back when you create the order, so the server honors the fixed price.

const { items } = await Products.getProducts([], "en_US", {
signPrice: "orders"
});

const signedPrice = items[0].signedPrice;

➡️ The returned token is consumed by createOrder(). See where to take it and how to pass it in the Fixed product price (signedPrice) section of the Orders module.


❓ Common Questions (FAQ)

Can I filter by multiple criteria at once?

Yes — pass several conditions in the body array; they are combined together:

const { items } = await Products.getProducts(
[
{ attributeMarker: "price", conditionMarker: "mth", conditionValue: 100 },
{ attributeMarker: "brand", conditionMarker: "in", conditionValue: ["apple", "samsung"] },
],
"en_US",
);

How do I handle product variants (sizes, colors)?

Variants are stored in the product's attributeValues — read them from the fetched product object. The structure is whatever attribute set you configured for the catalog.


How do I implement a "Load More" button?

Increase offset by limit on each click and append the new items to your list (use total to know when to stop).


Can I show products from multiple categories?

Yes — filter with the category attribute and the in condition marker, passing the list of category values.


How do I implement a "New Arrivals" section?

Sort by creation date: userQuery: { sortKey: "date", sortOrder: "DESC" }.


🎓 Best Practices

  • Always paginate (limit + offset) — never fetch the whole catalog at once.
  • Cache product lists for frequently accessed categories to reduce API calls.
  • Use signPrice when prices feed into a cart/checkout so the price can't drift.
  • Handle empty results (total === 0) and missing fields (price, images) gracefully.