Landed
Feedback widget

Widget installation

Embed the Landed feedback widget in your app with three copyable install steps.

This guide helps a workspace admin install the feedback widget in their own product, similar to UserJot's widget installation flow.

How hosting works

Your app only adds a few script tags. The widget SDK, embedded form, and API all run on Landed's URL (NEXT_PUBLIC_APP_URL — https://landed.so in production, http://localhost:3000 locally).

Your app loads scripts from Landed, not from your own domain:

<script src="https://landed.so/sdk/loader.js" async></script>

The loader fetches ld.js from the same origin, opens an iframe to https://landed.so/embed/widget, and sends submissions to Landed's public API. You never host the widget UI yourself.

Quick actions

What the widget does

  • Adds a floating feedback button inside your app
  • Opens an embedded feedback form without sending users elsewhere
  • Sends submissions into your Landed Inbox as conversations
  • Supports anonymous feedback and signed-in user attribution

Prerequisites

  • Admin access in Landed
  • Ability to edit your app HTML or root layout
  • A production or staging URL where you can paste a script tag

1. Open widget settings

  1. Open your workspace in Landed.
  2. Go to Settings → Widget (or use Share in the sidebar).

Each workspace gets one publishable key automatically when it is created (like a UserJot project ID). The key is public and safe to embed in client-side code. The widget is enabled by default, and the settings page shows three separate copyable install steps using that key.

2. Paste the install steps

Copy the three steps from widget settings and add them to your app, typically in the document <head> or root layout:

1. Load the SDK

<script src="https://landed.so/sdk/loader.js" async></script>

2. Initialize the widget

<script>
  // Queue calls until the loader finishes.
  window.$ldq = window.$ldq || [];
  window.ld = window.ld || new Proxy({}, {
    get: (_, method) => (...args) => window.$ldq.push([method, ...args]),
  });
  window.ld.init('wk_pub_YOUR_KEY', {
    position: 'right',
    theme: 'auto'
  });
</script>

The queue lines hold window.ld calls until the async loader finishes, so initialization works while loader.js is still downloading.

3. Identify signed-in users (optional)

<script>
  window.ld.identify({
    id: 'user_123',
    email: 'user@example.com',
    firstName: 'Jane',
    lastName: 'Doe'
  });
</script>

Replace wk_pub_YOUR_KEY with your workspace publishable key from settings. Use your Landed host for every script URL — the value of NEXT_PUBLIC_APP_URL (for example https://landed.so in production or http://localhost:3000 locally). There is no separate app. subdomain for the widget SDK.

3. Verify the widget

  1. Load your app in the browser.
  2. Confirm the feedback button appears in the bottom corner.
  3. Submit test feedback.
  4. Open Landed and confirm the submission appears as a conversation.

Install during onboarding

When you choose the widget during onboarding, the install steps appear in the conversation with your publishable key filled in. From there:

  1. Copy the install steps, or use Copy prompt to have your coding agent add the widget to your app.
  2. Load your app locally and send a test message. Onboarding shows Installed once the message arrives.
  3. Choose Finish later if you are not ready. You can continue from Settings → Widget or from Onboarding in the workspace menu.

Production verification updates after you deploy. It is optional and never blocks your workspace or your trial.

Framework notes

The widget is framework-agnostic. It works in:

  • Plain HTML sites
  • React, Next.js, Vue, Svelte, and other SPA frameworks
  • Server-rendered apps

If your framework strips inline scripts, load loader.js once in the root layout and call window.ld.init(...) after the user session is available.

Next step

If your users sign in, follow identify users so submissions are tied to the right person.