Skip to content
ForgeSaaSSign in

Getting started

Configuring your product

The one file that decides what your product is called, what colour it is, which languages it speaks and which modules it has.

product.config.ts at the repository root is the file a product edits. The template never modifies it, which is what makes it safe to pull template changes in later.

export const config = {
  name: "ForgeSaaS",
  primaryColor: "#7c6ff7",
  supportEmail: "[email protected]",
  modules: {
    billing: true,
    marketing: true,
    // ...
  },
  locales: { en: true, de: true, default: "en" },
} satisfies ProductConfig;

What each part reaches

name, primaryColor, supportEmail are read everywhere: the app shell, the transactional emails, this site’s header and its favicon. The brand colour in particular is written down exactly once — there is no stylesheet with a second copy of it, and a test fails the build if one appears.

modules switch features off. A disabled module takes its API routes, its database tables, its interface and its pages with it. Continuous integration builds several combinations, so “it works with everything enabled” is not the only thing that has been checked.

locales is the set of languages the product exposes. Turning one on adds its URLs across the app and this site; turning one off removes them, along with the alternate-language annotations that pointed at them.

The mirror on the backend

backend/product/config.py carries the same values for the Python side, and a test asserts the two agree. When you change one, change both — the test will tell you if you forget, but it is quicker to remember.

After a change

Module toggles affect the build, not just a running process, so a changed toggle needs a rebuild rather than a restart. The build cache knows about this file, so a rebuild after editing it will not be served from a cache made before the edit.