Config
The platform/config/ folder holds Litestore's fixed values, such as store copy, policies, timings and AI limits, as typed constants you change in code.
The platform/config/ folder contains the values that shape how the store behaves but that a store owner doesn't change in the admin: the store's identity and copy, order and refund policies, email timings, referral rules, social-proof thresholds, AI limits and pricing defaults.
Each file is plain TypeScript with typed constants and a one-line comment for each. Litestore has no JSON layer and no runtime config service. To change a value, edit the constant and redeploy. Environment variables don't go here, because env.ts declares them, and the few business settings a store owner does change (store details, currency, payments, notification email, AI autonomy) are admin settings.
Config folder
Site and copy
platform/config/site.ts exports the store's identity and combines it into one config object.
export const config = {
site: siteConfig,
metadata: metadataConfig,
copy: copyConfig,
}| Export | What it does |
|---|---|
siteConfig | It contains the store name, slug and description, and reads the email and URL from env.NEXT_PUBLIC_SITE_EMAIL and env.NEXT_PUBLIC_SITE_URL. Its affiliateUrl is the domain of the store's short links; addSearchParams() passes links on that domain through untouched, so affiliate links don't get their ref parameters rewritten. Its feeds entry holds the two RSS URLs that pages link to for feed discovery. |
metadataConfig | This Next.js Metadata object sets the OpenGraph image at /opengraph.png (1200×630), the summary_large_image Twitter card and the RSS alternates. |
platform/config/copy.ts holds the titles and descriptions of the storefront index pages: collections, categories and blog.
Storefront behaviour
platform/config/storefront.ts holds storefront switches and copy that aren't per-store admin settings.
| Constant | What it controls |
|---|---|
SEO_TITLE_TEMPLATE | The page title pattern, "%s · {site}". |
REVIEWS_ENABLED, WISHLIST_ENABLED | Whether reviews and the wishlist are on. |
HIDE_OUT_OF_STOCK_VARIANTS, SHOW_VARIANT_OPTION_NAMES | How the variant picker behaves. |
ANNOUNCEMENT_DISMISS_MODE, ANNOUNCEMENT_COOLDOWN_DAYS | How long a dismissed announcement bar stays hidden. |
NEWSLETTER_COPY, FOOTER_PAYMENT_METHODS, SOCIAL_PLATFORMS | Footer copy and icons. |
NEW_PRODUCT_DAYS (14), SALE_ENDS_SOON_HOURS (48), BESTSELLER_UNITS (50), SELLING_FAST_UNITS_24H (5) | The thresholds for the social proof on products, computed by productProof in modules/products/social-proof.ts. |
Store policies
platform/config/store-policies.ts holds the timings and limits that shape orders, refunds, shipping and support.
| Constant | Default |
|---|---|
CUSTOMER_CANCEL_WINDOW_HOURS | 2 |
REFUND_REQUEST_WINDOW_DAYS, REFUND_REQUEST_WINDOW_FROM | 30, from "delivery" |
REFUND_MAX_REQUESTS_PER_WINDOW, REFUND_VELOCITY_WINDOW_DAYS | 0 (no cap), 30 |
DEFAULT_HANDLING_DAYS, SHIPPING_WORKING_DAYS, SHIPPING_HOLIDAYS | 1, Monday to Friday, none |
PICKUP_UNCOLLECTED_AFTER_DAYS, SHIPMENT_MISSING_TRACKING_DAYS | 7, 1 |
REORDER_LEAD_TIME_DAYS, ORDER_INTENT_RETENTION_DAYS | 7, 90 |
MESSAGE_MAX_ATTACHMENTS, CURRENCY_ROUNDING_MODE | 5, "standard" |
Email automations and referrals
platform/config/email-automations.ts sets the cadence of the lifecycle emails: the abandoned-cart delay and follow-up, the optional recovery, win-back and welcome coupon codes, the review request and reminder, and the signup nudge. A delay of zero turns its step off. Workflows explains how they run.
platform/config/affiliates.ts sets the referral and collab rules: whether referrals are on, the reward points and how long a reward is held, the attribution window, collab coupon limits, the commission clearing period, the minimum payout and the default commission rate, and when a collab application is approved automatically.
AI limits
platform/config/ai.ts holds the cost and abuse ceilings every AI call runs under.
| Constant | Default | What it does |
|---|---|---|
AI_RATE_LIMIT | 20 requests per minute | The per-user ceiling for the admin AI routes. A chat turn is one request; tool steps inside it don't count again. |
AI_MONTHLY_BUDGET_USD | 50 | The store-wide spend ceiling per calendar month (UTC). Every model call is refused once month-to-date spend reaches it. 0 means unlimited. |
AI_MODEL_PRICES, AI_UNKNOWN_MODEL_PRICE | — | The list prices used to count spend. A model missing from the table is priced as the most expensive one, so the budget can only trip early. |
The file contains no model names, API keys or prompts. The admin assistant's system prompt and its settings (maxSteps 8, maxTokens 4000, temperature 0.3) are in modules/assistant/prompt.ts. It contains no list of tools, and a comment explains why: each registered tool describes itself through the AI SDK, and modules/assistant/agent-tools.ts is the only place that defines them. A hand-written tool list used to drift from the real tools.
Activity logging
Which writes Litestore records in the Activity table is decided in modules/operations/activity/config.ts. Every BaseCRUD model name belongs to one of four module lists.
| List | What Litestore logs | Examples |
|---|---|---|
CRITICAL_MODULES | Every operation | order, refund, user, customer, setting, product, review, campaign, serviceApiKey, page, feed, channel |
CREATE_DELETE_MODULES | Creates and deletes | media, tag, coupon, link |
DELETE_ONLY_MODULES | Deletes only | productVariant, externalLink, stockLocation, productRelationship |
SKIP_LOGGING_MODULES | Nothing | activity, address, wishlist, cart, notification |
A module that is missing from all four is skipped without any warning and has no audit trail, so add a new module's model to a list when you create it.
Litestore always logs the operations in CRITICAL_OPERATIONS, whichever module they happen in:
delete
refund
cancel
ban
suspendACTIVITY_CLEANUP keeps activity for 90 days and deletes old rows in batches of 1,000. Litestore never purges activity types that start with one of the DURABLE_ACTIVITY_TYPE_PREFIXES:
commission
payout
affiliatePayout
price_changed
setting
campaign
refund
return
payment
loyaltyLitestore deliberately doesn't keep routine order and product changes forever. An order's financial history can always be rebuilt from the PaymentTransaction and Order tables.
shouldLogActivity(module, operation) applies all of these rules.
Activity display
modules/operations/activity/registry.ts holds ACTIVITY_MODULES, the modules the activity feed filters by, and ACTIVITY_REGISTRY, which gives each activity type an icon, a color, a label, its module and a sort priority. You read it with getActivityConfig.
Design
The storefront has one design and no theme registry. Its colours, corners and spacing are CSS variables in app/styles.css, so you change the look there rather than in platform/config/. See Storefront pages.
Fonts
platform/config/fonts.ts loads a single typeface, once. fontSans is Figtree Variable, served from public/fonts/Figtree-Variable.woff2 with display: "swap", and the app reads it as --font-sans. The WOFF2 file is 27.8 KB compressed, compared with 62.7 KB for the TTF.
A comment at the top of the file explains why a second font was removed. A second localFont() call for --font-display added a duplicate @font-face and a duplicate preload, but looked no different, because the variable font's weight axis already reaches 700.
The file also exports loadGoogleFont(font, weight). It fetches a Google Fonts CSS2 stylesheet and returns the font file. Litestore uses it to render OG images with Satori, not for the app itself.
Payments and pricing
platform/config/payments.ts exports one list, SHIPPING_ALLOWED_COUNTRIES. It contains 24 ISO 3166-1 alpha-2 country codes, typed as Stripe's AllowedCountry union. Checkout uses it to determine which countries a shopper can enter as a shipping address.
platform/config/pricing.ts sets the default values for fees, margins and discounts.
| Constant | What it does | Default |
|---|---|---|
DEFAULT_PAYMENT_FEE_PERCENT | This is the assumed percentage payment processing fee. | 2.9 |
DEFAULT_PAYMENT_FEE_FIXED | This is the assumed fixed payment processing fee. | 0.3 |
DEFAULT_PLATFORM_FEE_PERCENT | This is the default platform fee. | 0 |
DEFAULT_MIN_MARGIN_PERCENT | This is the default minimum margin. | 5 |
BEHAVIORAL_DISCOUNTS | It configures four discounts: first_purchase, cart_abandoner, returning_customer and high_intent. Only first_purchase is enabled, and it gives 10% off, capped at 20, with priority 100. | — |
A cart only ever gets one behavioral discount. If several apply, Litestore picks the one with the highest priority.
External services
platform/config/external-services.ts is a lookup table of about 50 third-party services. Each entry has an id, a display name, a website, a favicon URL and one of eleven categories:
payment
social
analytics
ads
email
storage
auth
shipping
ecommerce
ai
otherEvery favicon loads through Google's favicon service, so the admin shows them all at the same size.
export function getService(id: string): ExternalService | undefined {
return EXTERNAL_SERVICES[id]
}getServiceFavicon(idOrUrl, size) returns the favicon for a known service or for any URL.
Adding config values
| What you're adding | Where it goes |
|---|---|
| Storefront index page wording | platform/config/copy.ts |
| Store identity | platform/config/site.ts |
| A storefront switch or threshold | platform/config/storefront.ts |
| An order, refund or shipping timing | platform/config/store-policies.ts |
| Storefront colours, corners or spacing | The @theme block in app/styles.css |
| A module that writes to the database | One of the four lists in modules/operations/activity/config.ts, and ACTIVITY_MODULES if its rows should be filterable |
| A third-party service | platform/config/external-services.ts |
Two kinds of values don't belong here. Anything that differs between environments goes in env.ts. Anything a store owner would change in Shopify's admin, such as store details, currency or payments, is an admin setting.
Related
Configuration
env.ts requires some environment variables, leaves others optional, and each optional group turns on one service.
Storefront pages
Storefront pages keep their content and feed in the database, and the storefront's design lives in a few files you edit directly.
Structure
The repository has a fixed layout, the code follows shared conventions, and each new module or integration has a place it belongs.