Skip to content

Embedding the Feedback Board

Embed your Canviq board directly in your product so users never leave your app to submit feedback.


Simple iframe Embed

The fastest option — no server code required.

<iframe
  src="https://{your-slug}.canviq.app/en"
  style="width: 100%; height: 600px; border: none;"
  title="Product feedback"
  loading="lazy"
/>

Replace {your-slug} with your organization's board slug (visible in your board URL).

The embedded board is fully functional: users can submit feedback, vote, comment, and view the public roadmap — all within the iframe.


Authenticated Embed

By default, users in an iframe must log in to Canviq separately (via magic link). For a smoother experience, you can pre-authenticate your users using a signed embed token — they arrive at the board already signed in.

!!! info "Coming soon" Authenticated embed tokens are planned. No tracking issue yet — contact [email protected] if this is blocking your integration.

Once available, the flow will work like this:

// Server-side only — NEVER put your API key in client-side code
const res = await fetch('https://canviq.app/api/embed-tokens', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CANVIQ_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    user_email: currentUser.email,
    user_name: currentUser.displayName,
    expires_in: 3600, // seconds — token is single-use
  }),
})
const { token } = await res.json()

// Pass the token to your frontend (e.g. as a prop or in a meta tag)
const embedUrl = `https://${ORG_SLUG}.canviq.app/en?embed_token=${token}`

Then in your frontend:

<iframe
  :src="embedUrl"
  style="width: 100%; height: 600px; border: none;"
  title="Product feedback"
/>

The token is single-use and expires after expires_in seconds. Generate it on each page load.

Security Notes

  • Embed tokens are short-lived (max 1 hour) and single-use
  • Never cache or reuse a token across users
  • The API key used to generate tokens must have submissions:write scope
  • Tokens are scoped to the user email — they cannot be used to impersonate another user

Embedding Specific Views

Navigate to the appropriate path to control which view opens:

URL View
https://{slug}.canviq.app/en Default board (submission list)
https://{slug}.canviq.app/en/roadmap Public roadmap
https://{slug}.canviq.app/en/submit Submission form pre-opened
https://{slug}.canviq.app/en/submissions/{id} Specific submission detail

Responsive Sizing

<!-- Full-height embed using CSS -->
<div style="position: relative; padding-bottom: 75%; height: 0;">
  <iframe
    src="https://{your-slug}.canviq.app/en"
    style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none;"
    title="Product feedback"
  />
</div>

Or use a fixed minimum height that works for most viewports:

<iframe
  src="https://{your-slug}.canviq.app/en"
  style="width: 100%; min-height: 600px; border: none;"
  title="Product feedback"
/>

Content Security Policy

If your app uses CSP, add *.canviq.app to your frame-src directive:

Content-Security-Policy: frame-src https://*.canviq.app;

Alternatives to iframe

If embedding an iframe doesn't fit your UX, consider: