Skip to content

Golden Path β€” Frontend entity mapping (registerForFrontendGeneration) ​

After your plugin index.ts finishes, the plugin loader registers the plugin for frontend config generation with registerPluginForFrontendGeneration(pluginOptions, {}) β€” unless your plugin already called fastify.registerForFrontendGeneration, or opted out.

Default (no code in your plugin) ​

You can omit any call: the empty registration is applied automatically so generated-config.ts generation can run.

Customize options ​

Call fastify.registerForFrontendGeneration(options) from your plugin when you need:

  • entityMapping β€” rename how an entity appears in generated frontend config (discouraged unless necessary).
  • routePrefix, customConfig β€” advanced overrides (see core implementation and types on PluginFastifyInstance).

Your call replaces the default registration for this plugin (last explicit wins if you call more than once).

Rename example (snippet) ​

typescript
// Optional: only use entityMapping when you intentionally want to rename
// the generated frontend model key. If key === value, omit this call.
fastify.registerForFrontendGeneration({
  entityMapping: {
    example: "frontendExample",
  },
})

What generated-config.ts contains (excerpt) ​

After a successful backend generation run, each plugin has a frontend/generated-config.ts file. It is not hand-edited; see the generated config FAQ for field-by-field reference and Backend overview β€” generated-config lifecycle for when it is rewritten.

Below is a short excerpt (from the playground todo plugin) showing how one entity exposes operations with HTTP metadata, storeActionType, and channels:

typescript
export default {
  pluginName: "example-todo",
  author: "pacifico",
  pluginKey: "pacifico__example-todo",
  routePrefix: "/pacifico__example-todo",
  pluginPath: "/app/src/appPlugins/pacifico__todo",
  data: {
    todo: {
      type: "todo",
      operations: {
        getAll: {
          target: "/pacifico__example-todo/todo/all",
          method: "get",
          storeActionType: "dataRead",
        },
        create: {
          target: "/pacifico__example-todo/todo",
          method: "post",
          storeActionType: "dataCreate",
          channels: [
            {
              channel: "pacifico__example-todo--todoCreated",
              channelKey: "todoCreated",
              prefix: "pacifico__example-todo",
            },
            {
              channel: "dataCreated",
              channelKey: "broadcastDataCreated",
              prefix: "",
            },
          ],
        },
        updateCheckTask: {
          target: (payload) =>
            `/pacifico__example-todo/todo/checkTask/${payload._id}`,
          method: "patch",
          storeActionType: "dataUpdate",
          channels: [
            /* … */
          ],
        },
      },
    },
  },
}

Operation names in generated-config ​

The generator walks each registered route and derives:

  1. entityName β€” first URL segment after the plugin prefix (or a value from entityMapping).
  2. operationName β€” starts from the HTTP method, then appends PascalCase tokens built from remaining non-parameter path segments.

The HTTP verb is first mapped to a short verb prefix (from getMethodMapping in @raclettejs/core/services/backend/src/core/pluginSystem/configGenerator/index.ts):

typescript
const getMethodMapping = (httpMethod: string): string => {
  const methodMapping: Record<string, string> = {
    get: "get",
    post: "create",
    patch: "update",
    put: "update",
    delete: "delete",
  }
  return methodMapping[httpMethod] || httpMethod
}

Examples:

  • GET …/todo/all β†’ getAll (only all after the entity segment).
  • PATCH …/todo/checkTask/:id β†’ updateCheckTask (update + CheckTask).

Custom verbs fall through as-is when not in the table, so unusual methods still produce deterministic keys β€” but standard CRUD verbs give the predictable names the frontend helpers expect.

Opt out entirely ​

If a backend plugin must not participate in frontend generation registration:

typescript
fastify.registerForFrontendGeneration(false)

The loader will then not add the automatic {} registration.

See also ​