Start typing to search...
Docs
Publishing and maintaining templates
Sharing rich previews and custom metadata
Search

Sharing rich previews and custom metadata

When a user shares a remix of your template on social media, the Koji platform renders a rich preview (Open Graph) image based on a screenshot of the Koji. By default, the platform takes a screenshot of the initial view.

In some cases, the initial view might not be the best preview image for your template. For example, if a game template starts with an instruction screen, a screenshot of the first level might provide a better preview image. To improve the sharing experience in these cases, you can render a custom view of your template that is designed specifically to make an impression when sharing a remix. You can also control the timing of the screenshot to ensure that all relevant assets have loaded before the preview image is generated.

You can also customize the sharing metadata by configuring an entitlement.

Customizing the sharing image

To customize the sharing image for your template, render a custom view when the URL contains the koji-screenshot=1 query parameter. For optimal rich preview support, design this view with the following considerations in mind.

  • The image is responsive.

  • The image looks good with a square aspect ratio.

  • The image is optimized for faster loading. For example, to reduce the image size to 400x400 pixels and load only the first frame of a gif, you can add query parameters at the end of your image’s URL: https://images.koji-cdn.com/path/to/myimage.gif?fit=bounds&width=400&height=400&frame=1

  • The image includes customizable elements to generate unique previews of each remix.

Render a view for the rich preview image

For the following example, assume the template supports remixes of the title, font size, and logo.

  1. In your application code, add a conditional statement to display a different image for social shares. For example:

    React
    Vanilla JS
    Angular
    Svelte
    Example 1. React

    Add a conditional statement in the render function.

    render() {
      if (window.location.search.includes('koji-screenshot=1')) {
        return (
          <SocialSharePreview>
              <H1
              fontSize={this.state.titleOptions.fontSize}
              >{this.state.titleOptions.title}</H1>
              <Image src={this.optimizeURL(this.state.logo)} />
            </SocialSharePreview>
        );
      }
      ...
    }
    Example 2. Vanilla JS

    Wrap a conditional statement around the render function.

    // render the social share preview
    const socialShareRender = () => {
        document.body.innerHTML = `
            <div id="socialSharePreview">
                <h1 style="font-size:${titleSize}px" id="title">${title}</h1>
                <img id="logo" src="${optimizeURL(logo)}"/>
            </div>`;
    }
    
    // render
    if (window.location.search.includes('koji-screenshot=1')) {
        socialShareRender();
    } else {
        render();
    }
    Example 3. Angular

    Add a conditional statement in the ngOnInit function and use it to apply a dynamic id.

    app.component.ts
    app.component.html
    app.component.ts
    ngOnInit() {
      ...
      this.social = false
      if (window.location.search.includes('koji-screenshot=1')) {
        this.social = true
      }
      ...
    }
    app.component.html
    <div class="container" id="{{social ? socialSharePreview : ''}}">
            <h1 style="fontSize: {{titleOptions.fontSize}}px;">{{titleOptions.title}}</h1>
            <img src="{{optimizeURL(logo)}}"
        />
        </div>
    Example 4. Svelte

    Add a conditional statement in the App.svelte file.

    {#if (window.location.search.includes('koji-screenshot=1'))}
        <div class="social-share" style="background-image: url('{optimizeURL(image)}');">
        <h1 style='font-size: {titleOptions.fontSize}px'>{titleOptions.title}</h1>
        </div>
    {:else}
    ...
    {/if}
  2. Define appropriate styles for the rich preview image.

    To ensure that it is displayed correctly, design the rich preview image as a responsive square.

    React
    Vanilla JS
    Angular
    Svelte
    React
    const SocialSharePreview = styled.div`
      background-color: #395b88;
      min-height: 100vh;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      font-size: calc(10px + 2vmin);
      text-align: center;
      color: #fcfcfc;
    `;
    Vanilla JS
    #socialSharePreview {
      background-color: #395b88;
      min-height: 100vh;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      font-size: calc(10px + 2vmin);
      text-align: center;
      color: #fcfcfc;
    }
    Angular
    #socialSharePreview {
      background-color: #395b88;
      min-height: 100vh;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      font-size: calc(10px + 2vmin);
      text-align: center;
      color: #fcfcfc;
    }
    Svelte
    .social-share {
      background-color: #395b88;
      min-height: 100vh;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      font-size: calc(10px + 2vmin);
      text-align: center;
      color: #fcfcfc;
    }
  3. To test the preview image, open your staging link and append ?koji-screenshot=1 to the URL.

Controlling the screenshot timing

The Koji platform uses the window.kojiScreenshotReady property to determine the timing of the rich preview screenshot.

When the platform loads a template, it checks for window.kojiScreenshotReady = false;. If this value isn’t present, the platform takes the screenshot right away. If it is, the platform sets an interval to check the value every 100ms. When the value changes to true or a maximum interval of 2000ms elapses, the platform takes the screenshot.

This feature enables you to ensure that the relevant fonts, images, videos, and other assets have loaded before the sharing image is generated. For example:

  1. In the index.html file, add the following script tag.

    <script> window.kojiScreenshotReady = false; </script>
  2. In your application code, add the following code after confirming that the relevant assets have loaded.

    window.kojiScreenshotReady = true;

Customizing the sharing metadata

To enable custom metadata when sharing a Koji on social media, configure the CustomMetadata object in the .koji/project/entitlements.json file.

{
  "entitlements": {
    "CustomMetadata": {
      "enabled": true, (1)
      "metadata": {
        "title": "{{settings.title}}", (2)
        "description": "{{settings.description}}" (3)
      }
    }
  }
}
  1. enabled – Whether to use custom metadata when a creator shares a remix of this template.

  2. metadata.title – Path to the Visual Customization Control (VCC) that defines the title, if custom metadata is enabled.

  3. metadata.description – Path to the VCC that defines the description, if custom metadata is enabled.