Start typing to search...

@withkoji/vcc (deprecated)

Warning

This package is deprecated and is included only for backwards compatibility. For new templates, use withkoji-koji-core.html.

The @withkoji/vcc package enables you to implement core platform features in your Koji template, including instant remixing, Visual Customization Controls (VCCs), and the Koji feed.

  • Dynamically get and set custom values in Koji customization files.

  • Expose VCCs so that a user can change the customizable elements in your template.

  • Monitor changes to custom values with a watcher function.

  • Ensure the template is displayed correctly in the Koji feed.

  • Monitor and handle state transitions between in and out of focus in the Koji feed.

  • Define distinct template experiences for different viewing contexts.

Install

Install the package in your Koji project.

npm install --save @withkoji/vcc

Start the watcher

Reconfigure the package.json file to run the watcher (koji-vcc watch) concurrently with your development server. You can use a package like npm-run-all. For example:

Install npm-run-all.

npm install --save-dev npm-run-all

Modify the package.json file.

{
  "scripts": {
    ...
    "start": "npm-run-all -p watch start:server",
    "watch": "koji-vcc watch",
    "start:server": "webpack-dev-server --config ./.internals/webpack.development.js --inline --hot"
  }
}
Warning
Make sure to replace the value of "start:server" with the "start" command for your project and remove the prestart command, if there is one.

Support TypeScript

To ensure that VCCs work correctly in your TypeScript project, add the following line to the scripts section of the package.json file.

"prebuild": "koji-vcc preinstall-ts"

This command builds the VCC configuration files before compiling your TypeScript code when publishing the template, similar to how koji-vcc watches the files during development. This step is necessary to prevent errors by TypeScript during compile time.

InstantRemixing

Instant remixing enables users to customize values directly from the template preview, rather than from the Koji editor, for a quick and easy way to remix without coding.

Important
To empower casual users, implementing instant remixes for your templates is strongly recommended.

To enable instant remixing for your Koji template, you must implement the InstantRemixing class and enable the InstantRemixing entitlement.

new InstantRemixing()

Instantiates InstantRemixing.

Example

import { InstantRemixing } from '@withkoji/vcc';
const instantRemixing = new InstantRemixing();

InstantRemixing methods

.finish()

Advances a Koji from a remix to a preview.

Important
If the InstantRemixingNativeNavigation entitlement is enabled, this method must be called to advance the remix, as the Koji remix editor will not show the default action. You can use this option to handle validation and other processing before advancing to a preview.

Example

<button onClick={() => instantRemixing.finish()}>
  Next
</button>

.get(path)

Gets initial values from Koji customization files or one of these predefined environment values:

  • metadata – project data, contains projectId, the unique identifier for the Koji project.

  • serviceMap – endpoints for your currently registered services.

Parameters

  • path – Array of Strings, keys pointing to the desired VCC value, metadata and projectId, or serviceMap and the service name.

Returns

Any, value of the VCC type at the specified path. For the predefined environment values, the following values are returned:

["metadata", "projectId"]

String, the unique identifier for the Koji project.

["serviceMap", "backend"]

String, URL of the service specified in the second part of the path.

Example

const myVariable = instantRemixing.get(['scope', 'key']);
const projectId = instantRemixing.get(['metadata', 'projectId']);
const backendService = instantRemixing.get(['serviceMap', 'backend']);

.onPresentControl(path, attributes)

Opens a VCC to enable editing of a custom value. For example, show the title VCC when a user taps an editable title.

Parameters

  • path – Array of Strings, keys pointing to the VCC value.

  • attributes – (Optional) Object, contains the position object, which sets an absolute position for the VCC. If an absolute position is not set, the VCC opens in the position where the user clicks, in desktop view.

Example

instantRemixing.onPresentControl(['scope', 'key']);

// With optional position object
this.instantRemixing.onPresentControl(['result', 'position'], {
  position: { x: 100, y: 100 },
});

.onSetActivePath(handler)

Listens to the path of the currently active VCC control to enable a different experience when editing values (for example, highlight the active control or pause the interface).

Parameters

  • handlerFunction, handles changes to the current control. Receives the following property as input:

    • path – Array of Strings, the path of the active VCC control.

Example

instantRemixing.onSetActivePath((path) => {
  // Change control experience
});

.onSetCurrentState(handler)

No longer supported. For the most flexibility and control of the remix experience, implement the @withkoji/core package.

.onSetRemixing(handler)

Listens to changes in remix state to enable different template experiences during remix than during preview or use.

Parameters

  • handlerFunction, handles changes in remix state. Receives the following properties as inputs:

    • isRemixingBoolean, indicates whether the template is in remixing mode.

    • editorAttributesObject, describes the current editor. Contains the following attributes:

      • typeString, describes the current editor type, either full for the Koji editor or instant for an instant remix.

      • modeString, distinguishes between a new remix and an edit to the user’s existing Koji.

Example

instantRemixing.onSetRemixing((isRemixing, editorAttributes) => {
  // Change template experience
});

.onSetValue(path, newValue, skipUpdate)

Explicitly sets the value for the VCC at the specified path.

Parameters

  • path – Array of Strings, keys that points to the desired VCC value.

  • newValueAny, New value for the VCC type at the specified path.

  • skipUpdate – (Optional) Boolean, indicates whether to skip the onValueChanged callback for this update (false, by default). To allow the template to manage the update state, set this parameter to true.

    Tip
    The skipUpdate option is useful for preventing unnecessary round trip notifications in some cases. For example, during text inputs.

Example

instantRemixing.onSetValue(['scope', 'key'], newValue, skipUpdate);

.onValueChanged(handler)

Listens to changes in custom values.

Parameters

  • handlerFunction, handles changes to custom values. Receives the following properties as inputs:

    • path – Array of Strings, the path of the changed VCC value.

    • newValueAny, the new value of the changed VCC.

Example

instantRemixing.onValueChanged((path, newValue) => {
  // Use new custom value in template
});

.ready()

Indicates that the application is ready to start receiving events.

Warning
All the listeners should be set before calling ready(). The platform will queue any messages prior to calling ready() to wait for the listeners to be ready. However, the get function will work before or after ready() has been called.

Example

instantRemixing.ready();

VccMiddleware

This package includes an Express middleware to manage the environment variables for instant remixes and for access to VCC values from dynamic backends, as a companion to the frontend InstantRemixing class.

To implement this middleware, add it to your Express server.

import { VccMiddleware } from '@withkoji/vcc';

const app = express();
app.use(VccMiddleware.express);

This middleware is required to manage the environment variables to scope them for instant remixes of the original template. In particular, when using withkoji-koji-iap-package.html, withkoji-database-package.html, or withkoji-koji-auth-sdk.html, you must call this middleware before instantiating those packages to ensure they use the correct environment.

Additionally, to access application-specific VCC values from an Express endpoint, use res.locals.koji and the scope and key of the VCC value you require.

app.get('/test', (req, res) => {
  // res.locals.koji.scope.key
});

FeedSdk

The Koji feed enables users to browse available templates, moving them from off screen or out of focus, into the main window of the feed.

To ensure a template can be displayed correctly in the Koji feed, you must implement the FeedSdk and enable the entitlement.

new FeedSdk()

Instantiates FeedSdk.

Example

import { FeedSdk } from '@withkoji/vcc';
const feed = new FeedSdk();

FeedSdk methods

.createRemix(options)

Starts a new remix.

Parameters

  • options – (Optional) Object, configuration options for the remix. Contains the following property:

    • id – (Optional) String, ID of the Koji project to remix. Defaults to the current Koji, if an ID is not specified.

Example

<button type="button" onClick={() => feed.createRemix()}>
  Create my own remix
</button>

.load()

Indicates the template is ready to display and registers touch event handlers to bubble up touch events to the feed controller (if your template needs to own a gesture, see requestCancelTouch).

Important
You must call this method when the template has loaded. Otherwise, the feed will display a loading state, and will eventually time out and move to the next template in the feed.

Example

feed.load();

.navigate(url)

Replaces the currently loaded Koji with the content at the specified URL, without triggering a browser navigation event. This method enables a smoother experience in embedded contexts.

Note
If the site at the specified URL can’t be rendered in a frame (the x-frame-options header prevents it), the user is prompted to navigate at the browser level.

Parameters

  • urlString, URL of the content to load.

Example

<button type="button" onClick={() => feed.navigate(url)}>
  My favorite Koji
</button>

.onPlaybackStateChanged(handler)

Monitors visibility in the Koji feed, enabling the template to play certain features when it is in focus and pause them when it isn’t in focus. For example, play or pause audio, video, a timer, or a countdown.

Tip
To test autoplaying features, you can open a published template and append ?feedDebug=true to the URL. The template is loaded in the feed 10 times, and you can swipe or scroll through to ensure the features start and stop as expected.

Parameters

  • handlerFunction, handles changes to template visibility in the feed. Receives the following property as input:

    • isPlayingBoolean, indicates whether the template is in focus in the feed.

Example

feed.onPlaybackStateChanged((isPlaying) => {
  // Handle autoplay features
});

.present(url)

Opens the content at the specified URL in a modal window that animates from the bottom of the screen. If the parent Koji is already displayed in a modal window, the content will open in the same window, replacing the current view.

Note
If the site at the specified URL can’t be rendered in a frame (the x-frame-options header prevents it), the user is prompted to navigate at the browser level.

Parameters

  • urlString, URL of the content to load.

Example

<button type="button" onClick={() => feed.present(url)}>
  My favorite Koji
</button>

.requestCancelTouch()

Cancels touch event handlers for the feed so that the template can use the gesture. If your template uses gestures, you can use this method at any time during the touch lifecycle to take control of the action.

Tip
Because a feed is composed of iframes, the parent feed control can’t capture touch events due to security policies. Therefore, the load method bubbles up touch events to the Koji feed controller so that users can browse templates in the feed. If your template also uses touch controls, you can use the requestCancelTouch method to ensure the template actions take precedence over the feed actions for those controls.

Example

<div ontouchmove={(e) => feed.requestCancelTouch()}>
  no touch control
</div>

.share()

Opens the sharing menu.

Example

<button type="button" onClick={() => feed.share()}>
  Share my Koji
</button>

FeedSdk services

context

Enables distinct template experiences for different viewing contexts.

URL pattern

?context={value}

Parameter values

  • about – Manages the context for the remix landing page (About page).

  • admin – Manages functionality designed for the creator of a Koji.

  • remix – Manages the context for Kojis during a remix.

  • sticker – Manages the context for Kojis embedded in iframes in other Kojis.

Example

// Load the remix experience
if (searchParams.context === 'remix') {
  return <Remix />;
}

Keystore

The Keystore module is used in conjunction with the secret VCC type. The secret VCC enables you to store sensitive data in a VCC without the value being visible when the project is remixed. Keystore is used to access the value in the secret VCC within your application code.

Note
For security purposes, Keystore is available only in backend services and cannot be used in user-facing services.

new Keystore(projectID, projectToken)

Instantiates Keystore.

Parameters

  • projectIdString, unique ID of the Koji project to attach the keystore to.

  • projectTokenString, token of the Koji project to attach the keystore to.

Tip
These parameters are available as environment variables at runtime. For instant remixes, you must implement VccMiddleware to manage these variables.

Example

import { Keystore } from '@withkoji/vcc';
const keystore = new Keystore(
  res.locals.KOJI_PROJECT_ID,
  res.locals.KOJI_PROJECT_TOKEN,
);

Keystore methods

.generateSignedUrl(resource, expirySeconds)

Generates a signed URL for securely serving a file that is stored in your project’s CDN, without exposing the permanent URI. This method provides additional security against sharing or rehosting of protected content.

Parameters

  • resourceString, full URL of the file on your CDN.

    Note
    If you want to use query parameters, apply them to the signed URL rather than the resource argument. For example, when resizing or cropping images.
  • expirySeconds – (Optional) Number, amount of time for which the signed URL remains valid, in seconds. If undefined, signed videos expire after 1 hour, and any other resource expire after 5 minutes.

Returns

(Async) String, signed URL for the requested resource. For example, the signed URL for a standard video file will look something like https://objects.koji-cdn.com/signed/TOKEN. The signed URL for an HLS video file will follow a slightly different pattern.

Example

const signedUrl = await keystore.generateSignedUrl(premium_image);
optimizedUrl = `${signedUrl}?format=jpg&optimize=medium`;

.resolveValue(keyPath)

Resolves a secret VCC value from its keypath.

Parameters

  • keyPathString, the key for the secret VCC. This is acquired from the VCC value of the secret type VCC.

Returns

(Async) String, value of the secret VCC.

Example

const password = await keystore.resolveValue(res.locals.koji.images.premium_image);