nuxt-clippy
Nuxt Clippy
Clippy and friends for your Nuxt 3/4 app.

Quick Setup
Install the module to your Nuxt application with one command:
npx nuxt module add nuxt-clippy
Pick an agent in nuxt.config.ts:
export default defineNuxtConfig({
modules: ['nuxt-clippy'],
nuxtClippy: {
// 'Clippy' | 'Bonzi' | 'F1' | 'Genie' | 'Genius' | 'Links' | 'Merlin' | 'Peedy' | 'Rocky' | 'Rover'
agent: 'Clippy',
// only bundle the agent above, see below
bundleAllAgents: false,
},
})
| Option | Default | Description |
|---|---|---|
agent |
'Clippy' |
Which agent to show. Can be overridden at runtime with the NUXT_PUBLIC_NUXT_CLIPPY_AGENT env variable. |
bundleAllAgents |
true |
Put all 10 agents in the build (~15MB) so agent can be switched at runtime. Set to false to build only the configured agent (~1.5MB), e.g. when your host limits deploy size. Browsers only download the agent in use either way. |
Usage
useClippy() is auto-imported. The agent loads in the browser after mount, so clippyAgent is undefined until then. Every component that calls useClippy() shares the same agent. Agents start hidden, so call show() first.
<script setup lang="ts">
const { clippyAgent } = useClippy()
const greet = () => {
clippyAgent.value?.show()
clippyAgent.value?.play('GetAttention')
clippyAgent.value?.speak('Hello, I am Clippy!')
}
</script>
<template>
<button :disabled="!clippyAgent" @click="greet">
Show agent
</button>
</template>
Actions
All the agent actions are queued and executed by order, so you could stack them. The agent is fully typed; the ClippyAgent type is auto-imported too.
const agent: ClippyAgent = clippyAgent.value!
// show / hide the agent (pass `true` to skip the animation)
agent.show()
agent.hide()
// play a given animation
agent.play('Searching')
// play a random animation
agent.animate()
// get a list of all the animations
agent.animations()
// => ["MoveLeft", "Congratulate", "Hide", "Pleased", "Acknowledge", ...]
// show text balloon, pass `true` as second argument to keep it open until `agent.closeBalloon()`
agent.speak('When all else fails, bind some paper together. My name is Clippy.')
// move to the given point, use animation if available
agent.moveTo(100, 100)
// gesture at a given point (if gesture animation is available)
agent.gestureAt(200, 200)
// stop the current action in the queue
agent.stopCurrent()
// stop all actions in the queue and go back to idle mode
agent.stop()
// remove the agent from the page
agent.dispose()
Licence
MIT
Special Thanks
- pi0 for clippyjs, which this module is built on
- lizozom for clippyts, which earlier versions used
- The Clippy.JS project by Smore
- The awesome Cinnamon Software for developing Double Agent the program we used to unpack Clippy and his friends!
- Microsoft, for creating clippy :)
Contribution
Local development
# Install dependencies
pnpm install
# Generate type stubs
pnpm dev:prepare
# Develop with the playground
pnpm dev
# Build the playground
pnpm dev:build
# Lint, type check, test
pnpm lint
pnpm test:types
pnpm test
# Release: bumps version, updates CHANGELOG.md, pushes the tag.
# CI publishes the tag to npm.
pnpm release
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 2.0.0 | ^3.0 | MIT | |
| 1.1.2 | ^3.0 | MIT |