
How to Add a Feedback Widget to Next.js, React, and Vue (Step-by-Step)
A practical, framework-specific guide to adding a customer feedback widget to your Next.js, React, or Vue application in under 2 minutes.
Adding a feedback widget to your web app should take minutes, not hours. This guide covers the exact steps for Next.js, React, and Vue — with code snippets you can copy and paste.
Before You Start
You'll need a Palmframe account and a project. Sign up at palmframe.com, create a project, and copy your project ID. That's all the setup required.
Next.js (App Router)
Next.js with the App Router requires a client component for web components. Create a simple wrapper:
// components/feedback-widget.tsx
'use client'
import 'https://cdn.palmframe.com/embed.js'
export default function FeedbackWidget() {
return <palmframe-widget project="your-project-id" />
}Or skip the npm package entirely and use the script tag approach in your root layout:
// app/layout.tsx
export default function RootLayout({ children }) {
return (
<html>
<head>
<script src="https://cdn.palmframe.com/embed.js" async />
</head>
<body>
{children}
<palmframe-widget project="your-project-id" />
</body>
</html>
)
}The script tag approach is simpler and works without any client component wrapper. The widget loads asynchronously, so it won't block your page render.
Next.js Pages Router
For the Pages Router, add the script and widget to _app.tsx:
// pages/_app.tsx
import Script from 'next/script'
export default function App({ Component, pageProps }) {
return (
<>
<Script src="https://cdn.palmframe.com/embed.js" strategy="afterInteractive" />
<Component {...pageProps} />
<palmframe-widget project="your-project-id" />
</>
)
}React (Vite, Create React App)
For a standard React app, add the script tag to your index.html and the widget to your App component:
<!-- index.html -->
<script src="https://cdn.palmframe.com/embed.js" async></script>// App.tsx
export default function App() {
return (
<div>
{/* Your app content */}
<palmframe-widget project="your-project-id" />
</div>
)
}That's it. The widget is a standard web component — it works in any React app without additional dependencies or configuration.
Vue 3
Vue 3 works the same way. Add the script to your index.html and use the widget in your App component:
<!-- index.html -->
<script src="https://cdn.palmframe.com/embed.js" async></script><!-- App.vue -->
<template>
<div>
<!-- Your app content -->
<palmframe-widget project="your-project-id" />
</div>
</template>If Vue warns about an unknown custom element, add the widget to your Vite config:
// vite.config.ts
import vue from '@vitejs/plugin-vue'
export default {
plugins: [
vue({
template: {
compilerOptions: {
isCustomElement: (tag) => tag === 'palmframe-widget',
},
},
}),
],
}Nuxt 3
For Nuxt 3, create a client plugin and add the widget to your app layout:
// plugins/palmframe.client.ts
export default defineNuxtPlugin(() => {
if (typeof window !== 'undefined') {
const script = document.createElement('script')
script.src = 'https://cdn.palmframe.com/embed.js'
script.async = true
document.head.appendChild(script)
}
})<!-- app.vue -->
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
<palmframe-widget project="your-project-id" />
</template>Svelte / SvelteKit
For SvelteKit, add the widget to your root layout:
<!-- src/routes/+layout.svelte -->
<svelte:head>
<script src="https://cdn.palmframe.com/embed.js" async></script>
</svelte:head>
<slot />
<palmframe-widget project="your-project-id" />Plain HTML
The simplest case — just two lines before