Skip to content

docs: document scriptUrl, the offline options, and the exported types - #54

Open
sidgaikwad wants to merge 2 commits into
unlayer:mainfrom
sidgaikwad:docs/script-url-and-options
Open

docs: document scriptUrl, the offline options, and the exported types#54
sidgaikwad wants to merge 2 commits into
unlayer:mainfrom
sidgaikwad:docs/script-url-and-options

Conversation

@sidgaikwad

Copy link
Copy Markdown
Contributor

Fixes #36.

scriptUrl (the actual bug)

scriptUrl is a fully implemented, fully tested prop — loadScript(scriptUrl), part of the remount effect's deps, covered by "forwards a custom scriptUrl to loadScript" and "remounts when scriptUrl changes". But it was absent from the props table, so the only supported way to pin an embed environment was undiscoverable short of reading the .d.ts.

Added, along with the caveat already written in its doc comment — the kind of thing people otherwise discover by breaking it:

One embed per page: the first loader to run installs window.ImageEditor and wins globally, so do not mix different scriptUrls across components.

The related gaps from the issue

Offline / self-hosted assets. offline, licenseUrl and env were named in the options row and explained nowhere — that's the entire offline and self-hosted-assets story. New section with a table and a worked example, plus a note that env is remount-tier.

TypeScript. Every example was JSX. Added a .tsx example and a table of the five exported types (ImageEditorProps, ImageEditorOptions, ImageEditorRef, ImageEditorInstance, ImageEditorSaveResult).

Verification

The TypeScript example isn't hand-waved — I extracted it from the README and compiled it against the real source types through the demo's tsconfig:

README TypeScript example COMPILES against the real source types

Prettier clean.

`scriptUrl` is fully implemented and tested but was absent from the props
table, so the only supported way to pin an embed environment was
undiscoverable outside the .d.ts. Add it, along with the doc comment's
caveat about one embed winning per page.

Also close the gaps around it:

- `offline`, `licenseUrl` and `env` were named in the options row but
  never explained anywhere. Give them a section with a worked example.
- Add a TypeScript usage example — every other example was JSX — and a
  table of the exported types.

The TypeScript example is verified to compile against the real source
types via the demo's tsconfig.
@vercel

vercel Bot commented Sep 4, 2026

Copy link
Copy Markdown

@sidgaikwad is attempting to deploy a commit to the Unlayer Team on Vercel.

A member of the Team first needs to authorize it.

@lucasbesen

Copy link
Copy Markdown
Member

@sidgaikwad One issue to fix: the new example combines offline: true with IMAGE_EDITOR_BASE_URL, but offline mode disables URL-based asset loading. With the standard CDN bundle and no injected asset map, frames and stickers won’t load, and custom fonts fall back.

Please separate URL-hosted assets from true offline usage, and document the asset-map and local-script setup required for offline operation.

The offline example combined offline: true with IMAGE_EDITOR_BASE_URL, but
offline turns off URL-based asset loading, so that configuration silently
produces an editor with no stickers, no frames and fallback text fonts.

In image-editor 2.4.0 the asset resolver is

  assetMap?.[path] ?? bundled[path] ?? (!offline && base ? `${base}/assets/${path}` : '')

with `bundled` empty in the CDN build, so with offline set and no injected
map every asset resolves to ''. Confirmed in the browser: offline plus a
valid IMAGE_EDITOR_BASE_URL gives 590 sticker <img> elements with 590 empty
src attributes; dropping offline alone takes that to 0.

Split the section in two:

- Self-hosting the editor assets — IMAGE_EDITOR_BASE_URL and scriptUrl,
  online, assets still resolved by URL.
- Offline mode — what it disables, plus the three things a working setup
  needs: locally served scripts, an asset map via setAssetsMap on the
  image-editor-ready event, and self-hosted UI fonts, since the Google
  Fonts stylesheet is not injected when offline.
@sidgaikwad

Copy link
Copy Markdown
Contributor Author

You are right, and the example was worse than merely misleading — it produces an editor with no stickers or frames at all. Fixed in 8165e91.

I traced it in the 2.4.0 bundle rather than guessing. The asset resolver is:

let assetMap = null;       // set by setAssetsMap()
const bundled = {};        // empty in the CDN build
// offline and base assigned at mount from options.offline / env.IMAGE_EDITOR_BASE_URL

resolve(path) =
  assetMap?.[path] ?? bundled[path]
    ?? (!offline && base ? `${base}/assets/${path}` : "");

offline gates the only branch that builds a URL, and bundled is empty, so with offline: true and no injected map every asset resolves to "".

Confirmed in the browser, with IMAGE_EDITOR_BASE_URL pointed at a valid CDN path:

config sticker <img> empty src
offline: true + IMAGE_EDITOR_BASE_URL 590 590
IMAGE_EDITOR_BASE_URL only 590 0

In the control the srcs resolve to https://cdn.unlayer.com/image-editor/2.4.0/assets/images/stickers/emoticons/afro.svg, which also confirms the ${base}/assets/<path> shape now documented.

What changed

Split into two sections that are no longer confusable:

Self-hosting the editor assetsIMAGE_EDITOR_BASE_URL + scriptUrl, still online, assets resolved by URL from your host. Explicitly called out as not offline mode.

Offline mode — leads with a callout that offline disables URL-based asset loading and that combining it with IMAGE_EDITOR_BASE_URL does not work, then documents the three parts of a real setup:

  1. Serve embed.js and the versioned bundle locally via scriptUrl.
  2. Inject an asset map with setAssetsMap, on the image-editor-ready event — which inject() dispatches synchronously before resolving its promise, so the map is in place before createEditor runs.
  3. Expect system UI fonts: the Google Fonts stylesheet (Inter, Open Sans) is only injected when !offline.

I also noted that a missing key resolves to "", so the map should be generated from the assets/ directory at build time rather than written by hand — there are 684 entries (590 stickers, 73 frames, 21 fonts).

One thing to confirm

I documented the map injection as window.__ImageEditorImpl__.setAssetsMap(...), because that is what the bundle actually exposes — but the dunder name suggests an internal. If there is a supported public path for this, or you would rather not advertise that global, tell me the preferred form and I will rewrite that block.

README TypeScript example still compiles; Prettier and lint clean.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs: scriptUrl prop is missing from the README props table

2 participants