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:writescope - 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:
Alternatives to iframe¶
If embedding an iframe doesn't fit your UX, consider:
- Submit via API — build your own feedback UI and forward submissions server-side
- iOS / Android in-app browser — open the full board in SFSafariViewController or Chrome Custom Tabs with seamless auth