Feedback widget for VuePress
Add PushFeedback to your VuePress site.
Prerequisites
- A PushFeedback project. Copy its project ID from Projects > your project > Snippet and replace
<YOUR_PROJECT_ID>in the examples. - A VuePress site and Node.js installed.
Examples use @latest. Replace it with a version number to pin a release.
Choose the client configuration for your VuePress major version.
The examples load the widget runtime from jsDelivr and import the installed stylesheet. For a local runtime, see self-hosted assets.
Installation
Floating button

npm install pushfeedback@latest
Create .vuepress/components/FeedbackWidget.vue:
<script>
import 'pushfeedback/dist/pushfeedback/pushfeedback.css';
export default {
mounted() {
if (document.querySelector('script[data-pushfeedback]')) return;
const script = document.createElement('script');
script.type = 'module';
script.src =
'https://cdn.jsdelivr.net/npm/pushfeedback@latest/dist/pushfeedback/pushfeedback.esm.js';
script.dataset.pushfeedback = '';
document.head.appendChild(script);
},
};
</script>
<template>
<div>
<component
:is="'feedback-button'"
project="<YOUR_PROJECT_ID>"
button-position="bottom-right"
modal-position="sidebar-right"
button-style="dark"
>Feedback</component
>
</div>
</template>
VuePress 2: create or merge into .vuepress/client.js:
import { defineClientConfig } from 'vuepress/client';
import FeedbackWidget from './components/FeedbackWidget.vue';
export default defineClientConfig({
rootComponents: [FeedbackWidget],
});
VuePress 1: add the component to .vuepress/config.js:
module.exports = {
globalUIComponents: ['FeedbackWidget'],
};
Inline button

npm install pushfeedback@latest
Create .vuepress/components/InlineFeedback.vue:
<script>
import 'pushfeedback/dist/pushfeedback/pushfeedback.css';
export default {
mounted() {
if (document.querySelector('script[data-pushfeedback]')) return;
const script = document.createElement('script');
script.type = 'module';
script.src =
'https://cdn.jsdelivr.net/npm/pushfeedback@latest/dist/pushfeedback/pushfeedback.esm.js';
script.dataset.pushfeedback = '';
document.head.appendChild(script);
},
};
</script>
<template>
<div>
<component
:is="'feedback-button'"
project="<YOUR_PROJECT_ID>"
button-position="default"
screenshot-positioning="true"
modal-position="center"
button-style="dark"
>Feedback</component
>
</div>
</template>
VuePress 2: create or merge into .vuepress/client.js:
import { defineClientConfig } from 'vuepress/client';
import InlineFeedback from './components/InlineFeedback.vue';
export default defineClientConfig({
enhance({ app }) {
app.component('InlineFeedback', InlineFeedback);
},
});
VuePress 1: components in .vuepress/components/ are registered automatically.
In either version, add <InlineFeedback /> after the content in a Markdown page.
Embedded form

npm install pushfeedback@latest
Create .vuepress/components/EmbeddedFeedback.vue:
<script>
import 'pushfeedback/dist/pushfeedback/pushfeedback.css';
export default {
mounted() {
if (document.querySelector('script[data-pushfeedback]')) return;
const script = document.createElement('script');
script.type = 'module';
script.src =
'https://cdn.jsdelivr.net/npm/pushfeedback@latest/dist/pushfeedback/pushfeedback.esm.js';
script.dataset.pushfeedback = '';
document.head.appendChild(script);
},
};
</script>
<template>
<div>
<component
:is="'feedback-modal'"
project="<YOUR_PROJECT_ID>"
embedded="true"
></component>
</div>
</template>
VuePress 2: create or merge into .vuepress/client.js:
import { defineClientConfig } from 'vuepress/client';
import EmbeddedFeedback from './components/EmbeddedFeedback.vue';
export default defineClientConfig({
enhance({ app }) {
app.component('EmbeddedFeedback', EmbeddedFeedback);
},
});
VuePress 1: components in .vuepress/components/ are registered automatically.
In either version, add <EmbeddedFeedback /> after the content in a Markdown page.
Like and dislike buttons
![]()
npm install pushfeedback@latest
Create .vuepress/components/FeedbackThumbs.vue:
<script>
import 'pushfeedback/dist/pushfeedback/pushfeedback.css';
export default {
mounted() {
if (document.querySelector('script[data-pushfeedback]')) return;
const script = document.createElement('script');
script.type = 'module';
script.src =
'https://cdn.jsdelivr.net/npm/pushfeedback@latest/dist/pushfeedback/pushfeedback.esm.js';
script.dataset.pushfeedback = '';
document.head.appendChild(script);
},
};
</script>
<template>
<div>
<p>Was this helpful?</p>
<div class="pushfeedback-thumbs-row">
<component
:is="'feedback-button'"
project="<YOUR_PROJECT_ID>"
rating="1"
button-position="default"
modal-position="center"
button-style="default"
custom-font="true"
screenshot-positioning="true"
hide-icon="true"
>
<svg
width="22"
height="22"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path d="M7 10v12" />
<path
d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H3a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L11 2a3.13 3.13 0 0 1 4 3.88Z"
/>
</svg>
<span class="pushfeedback-thumb-label">Helpful</span>
</component>
<component
:is="'feedback-button'"
project="<YOUR_PROJECT_ID>"
rating="0"
button-position="default"
modal-position="center"
button-style="default"
custom-font="true"
screenshot-positioning="true"
hide-icon="true"
>
<svg
width="22"
height="22"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path d="M17 14V2" />
<path
d="M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H21a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L13 22a3.13 3.13 0 0 1-4-3.88Z"
/>
</svg>
<span class="pushfeedback-thumb-label">Not helpful</span>
</component>
</div>
</div>
</template>
VuePress 2: create or merge into .vuepress/client.js:
import { defineClientConfig } from 'vuepress/client';
import FeedbackThumbs from './components/FeedbackThumbs.vue';
export default defineClientConfig({
enhance({ app }) {
app.component('FeedbackThumbs', FeedbackThumbs);
},
});
VuePress 1: components in .vuepress/components/ are registered automatically.
In either version, add <FeedbackThumbs /> after the content in a Markdown page.
Each button opens the form with its rating selected. The visitor still clicks Send to submit.
Verify the installation
Run your project's VuePress build command and open your site. Send a test message and confirm it appears in your PushFeedback project. Check allowed URLs if submission fails.