Embed Publishing and Loaders
The embed publishing path is the maintenance workflow for releasing Cal embed packages and keeping their runtime behavior aligned with the booking experience. In this repository, the embed area is not a single package: it is a small package family with a core runtime and a snippet package, both handled from the monorepo root during release. This page explains how maintainers should think about publishing, versioning, skeleton loader support, prerendering, preloading, and the operational limits documented for the embed runtime.
Sources: packages/embeds/README.md, package.json
Purpose and Scope
Use this page when you are changing embed packages, preparing a release, or evaluating what the current loader can show before the embedded booking page is fully available. The source README describes the embed folder as holding multiple embed flavors, with the core library written in vanilla JavaScript and the snippet package intended for installation on any website so it can fetch the core library automatically. That distinction matters during release: a snippet update and a core update can affect different parts of the integration surface, but they are published together through a repository-level script.
Sources: packages/embeds/README.md, package.json
Relevant Source Files
- packages/embeds/README.md — Defines the embed package family, manual NPM publishing steps, skeleton loader support matrix, prerendering notes, preloading notes, modal reuse caveat, and architecture overview.
- package.json — Provides the root workspace layout and the scripts used to build and publish embed packages, including the custom publish path for packages whose names match the embed workspace pattern.
- .changeset/README.md — Identifies the repository’s changesets folder as generated by the Changesets CLI for versioning and publishing multi-package repositories.
Package Family and Publish Contract
The source-level contract begins with the folder organization. The core package owns the runtime that manages embeds, while the snippet package is the small website-facing installer that can be placed on external pages and load the core library. Because the repository workspaces include packages under the embed folder, root scripts can target those packages consistently from the monorepo. The publish script does not simply publish everything in the repository; it builds the core and snippet packages with embed-specific public URL settings, then publishes workspaces selected by the embed package name pattern.
Sources: packages/embeds/README.md, package.json
The custom publish contract is important because the embed README explicitly says maintainers cannot use the normal Changesets publish command for this path. The reason given is workspace prefix handling: the documented workflow avoids a Changesets publish limitation around removing workspace prefixes. In practice, that means maintainers should treat the root publish script as the supported release entry point for embed packages rather than replacing it with a generic multi-package publish command. The script encodes both build order and environment assumptions, so it is part of the release procedure rather than a convenience alias.
Sources: packages/embeds/README.md, package.json
Changesets Workflow
The documented release flow starts at the repository root and uses Changesets for version intent before the custom publish command releases packages. First, run the changeset creation command and select only embed packages when prompted. That creates changelog files and records the summary that should become part of the package changelog. Next, run the versioning command to bump package versions as required. After review and merge, the release step uses the repository’s embed publishing script. The separate Changesets README confirms this folder is produced by the Changesets CLI for versioning and publishing multi-package or single-package repositories.
Sources: packages/embeds/README.md, .changeset/README.md, package.json
Compact command reference:
yarn changeset— Create changelog files and choose embed packages only for the embed release.yarn changeset version— Apply the required version bumps from the pending changesets.yarn publish-embed— Build and publish embed packages through the repository’s supported embed release script.yarn withEmbedPublishEnv— Run a command with the public embed library URL and web app URL used by the publish script.
The root script named withEmbedPublishEnv sets public embed and web application URLs before invoking Yarn. The publish script uses that environment wrapper to build the core package, then build the snippet package, and finally publish matching embed workspaces with public access. This sequence tells maintainers that release verification should include both generated package artifacts and the public URL assumptions embedded at build time. If a change affects how the snippet finds the core library or how the core opens an iframe, validate the built output before publishing rather than relying only on TypeScript or unit checks.
Sources: package.json, packages/embeds/README.md
Loader Behavior and Supported Page Types
The skeleton loader is a performance and perception feature, not a universal rendering mode. The README says it is shown only for supported page types, while unsupported page types fall back to the default non-skeleton loader. The supported matrix includes responsive layout, mobile layout, and month view layout, while week view and column view are not marked complete. Theme support includes dark and light themes, and system theme changes should reflect without a page refresh. The README also notes that an in-app user theme preference has to be communicated clearly to the embed for the skeleton to work correctly.
Sources: packages/embeds/README.md
Page type coverage is deliberately specific. Slot pages for user event booking and team event booking are marked supported. Booking form pages for user events and team events are marked only partially supported because they show a skeleton, but the skeleton is the slots page skeleton rather than a form-specific skeleton. Profile pages for users and teams are not marked supported. When testing a loader change, use that distinction to avoid overclaiming readiness: a visible skeleton on a form page does not mean the loader accurately represents the eventual form layout.
Sources: packages/embeds/README.md
Prerendering, Preloading, and Modal Performance
The embed README separates preloading from prerendering because they optimize different parts of the user experience. Preloading places the booking link in an iframe to warm static assets in the browser cache before the embed is opened. Prerendering continues from that preloaded iframe so the user books inside the already prepared iframe, which is more complex but can provide a larger performance benefit. The documented API relationship is that prerender delegates to the preload API, and that lower-level path determines whether the operation is only a preload or a full prerender.
Sources: packages/embeds/README.md
Routing prerendering uses a modal-oriented flow. The parent page asks an API to prerender a booking link for a modal. When the visitor clicks the call to action, the embed checks whether a prerendered or currently prerendering modal exists for the namespace. If it does, the modal opens with the skeleton loader while the system sends a request to the router endpoint. After the response arrives, query parameters are passed to the rendered or rendering iframe, and the iframe URL is updated through browser history replacement rather than by reloading the iframe.
Sources: packages/embeds/README.md
Modal reopening has a documented optimization boundary. The modal box can reuse the same modal element and iframe, which would make repeated opens of the same modal very fast. However, the README notes that this feature is currently disabled in code because of stale booking page user interface issues. Treat that as an implementation caution: do not assume iframe reuse is active when measuring current performance, and do not design user-facing guarantees around repeated modal opens unless the stale page issue has been fixed and the optimization has been re-enabled.
Sources: packages/embeds/README.md
Next Steps
For release work, start by creating a focused changeset for the affected embed packages, then verify the root publish script still builds both core and snippet with the expected public URL settings. For runtime work, test the exact page types listed in the loader matrix, including the partial booking form cases and unsupported profile pages. For broader context, read the embed overview and the core, snippet, and React embed pages so you can separate publishing mechanics from the runtime responsibilities of each package.