# Custom objects

> Save and load a Fabric.js custom object with its custom properties. Register the class once, get objects by id, and avoid fromObject errors.

Source: https://fabricjs-document-engine.jscrate.dev/docs/guides/custom-objects
Last updated: 2026-09-28

A Fabric.js custom object is a class that extends a Fabric.js class, often with extra properties. Plain `toJSON` drops those properties, and loading fails if the class is unknown. Register the class with the engine once, and both problems go away.

## Register a class

```ts
import { Rect } from "fabric";
import { createDocumentEngine } from "fabricjs-document-engine";

class Sticker extends Rect {
  static type = "Sticker";
  declare label: string;
}

const engine = createDocumentEngine({
  canvas,
  customObjects: [{ fabricClass: Sticker, properties: ["label"] }],
});
```

- `static type` must be set. It is the name saved in the document.
- `properties` lists the custom properties to save and load. You do not pass them on every save.

You can also register later, before loading a document that needs the class:

```ts
engine.registerObject({ fabricClass: Sticker, properties: ["label"] });
```

## Unknown types fail early

If a document contains a type that is not registered, loading fails with `UNKNOWN_OBJECT_TYPE` before the canvas is touched. `error.unknownTypes` lists the missing names. The object is never silently turned into a plain rectangle.

This replaces the confusing `klass.fromObject is not a function` error you get from plain Fabric.js when a class is missing. The engine registers your class with Fabric.js, so its `fromObject` is found.

## Get object by id

Every object gets a stable `id`, including your Fabric.js custom object and objects inside groups. Use it to link objects to your own data:

```ts
const sticker = engine.getObjectById("a1b2c3");
sticker?.set("label", "Kitchen");
```

The id survives moving, grouping, saving, undo and reopening. After undo, look objects up by id again, because the instance is new.

## Project data belongs in metadata

Keep data about the whole document, such as its title, owner or tags, in `metadata` rather than on objects:

```ts
engine.updateMetadata({ title: "Ground floor", owner: "user-42" });
```

## Two copies of Fabric.js

If your bundle contains two copies of `fabric`, a class registered in one is unknown to the other, and a Fabric.js custom object fails with `UNKNOWN_OBJECT_TYPE`. Make sure only one `fabric` is installed. See [troubleshooting](https://fabricjs-document-engine.jscrate.dev/docs/production/troubleshooting).
