Add an AI documentation assistant to a product, docs site, dashboard, SDK portal, or internal tool, then make it look like it belongs there.
Context7 indexes documentation and serves grounded answers through its hosted
chat widget. The official https://context7.com/widget.js script is fast to
install, but it exposes only a small styling and positioning surface. This
project keeps the same Context7 backend and install model, then adds the product
layer teams usually need before shipping a public support surface.
- Visitors can ask product and API questions without leaving your site.
- Existing Context7 users can replace the script URL instead of rewriting an integration.
- Product teams can match the widget to their brand, layout, and interaction model.
- Developers get typed helpers, events, framework bindings, and a stable CSS customization contract.
If you are not familiar with Context7 yet: think of it as hosted, searchable, AI-powered documentation for a library or product. After your library is available in Context7, this package gives you a polished widget layer for your own site.
| Surface | Use it when |
|---|---|
https://context7.desourcelabs.com/widget.js |
You want a drop-in script tag for HTML, Docusaurus, Next.js, Astro, Nuxt, Vite, or static pages |
@desource/context7-widget |
You want TypeScript helpers, the custom element, script generation, or direct runtime control |
@desource/context7-widget-vue |
You want a Vue 3 component, composable, plugin helper, typed events, and managed triggers |
@desource/context7-widget-nuxt |
You want Nuxt auto-imports, global defaults, automatic CSS, and SSR-safe Vue integration |
@desource/context7-widget-react |
You want a native React component, controlled state, hook, typed callbacks, and managed triggers |
@desource/context7-widget-svelte |
You want a native Svelte 5 component, bindable state, snippets, and reactive controls |
@desource/context7-widget-angular |
You want a standalone Angular component, signals, DI defaults, and injectable controls |
Vue, React, Svelte, and Angular own native framework UI and lifecycle while
sharing the headless conversation engine, renderer bridge, transport, Markdown,
types, defaults, and brand assets through @desource/context7-widget/kit. The
Nuxt module configures the Vue package without adding another renderer.
Replace the official Context7 script URL and keep data-library:
<script async src="https://context7.desourcelabs.com/widget.js" data-library="/owner/repo"></script>For a branded widget:
<script
async
src="https://context7.desourcelabs.com/widget.js"
data-library="/owner/repo"
data-position="anchor"
data-preset="glass"
data-theme="auto"
data-placeholder="Ask about setup, API usage, or examples..."
></script>The widget still calls https://context7.com/api/v2/widget/chat. This package
does not proxy, fork, or replace Context7; it improves the client experience.
Chat requests travel directly from the visitor's browser to Context7. The JSON
request contains the configured library id and the current conversation
messages, including each message's id, role, and content. DeSource Labs serves
the optional hosted widget.js file but does not proxy chat requests.
The client adds no analytics, cookies, or persistent browser storage;
conversation state is held only in the live widget's memory, and reset()
clears it. Host applications can listen to events containing questions and
answers, so only forward those payloads to analytics under your own privacy
policy. Do not put secrets or sensitive personal data into chat, and review
Context7's terms for backend processing and retention.
Swap the script origin. Your data-library, allowed-domain setup, and Context7
backend behavior stay the same.
<!-- Before -->
<script async src="https://context7.com/widget.js" data-library="/owner/repo"></script>
<!-- After -->
<script async src="https://context7.desourcelabs.com/widget.js" data-library="/owner/repo"></script>- Add or claim your library in Context7.
- Put the widget script in the root layout of your docs or product site.
- Choose a preset and position.
- Add CSS variables or
::part()overrides so the chat surface matches your UI. - Listen to events such as
c7:questionandc7:answer-completefor product analytics.
npm install @desource/context7-widget-vue<script setup lang="ts">
import { Context7Widget, type Context7WidgetQuestionEventDetail } from '@desource/context7-widget-vue';
import '@desource/context7-widget-vue/styles.css';
function trackQuestion(detail: Context7WidgetQuestionEventDetail) {
console.log(detail.library, detail.question);
}
</script>
<template>
<Context7Widget library="/owner/repo" position="anchor" preset="glass" theme="auto" @question="trackQuestion" />
</template>npm install @desource/context7-widgetimport { mountContext7Widget } from '@desource/context7-widget';
mountContext7Widget({
library: '/owner/repo',
position: 'center',
preset: 'glass',
backdrop: true,
closeOnOutsideClick: true
});npm install @desource/context7-widget-reactimport { Context7Widget } from '@desource/context7-widget-react/component';
import '@desource/context7-widget-react/styles.css';
export function DocsAssistant() {
return <Context7Widget library="/owner/repo" position="anchor" preset="glass" customTrigger />;
}npm install @desource/context7-widget-nuxtexport default defineNuxtConfig({
modules: ['@desource/context7-widget-nuxt'],
context7Widget: {
defaults: { library: '/owner/repo', preset: 'glass' }
}
});<Context7Widget /> and useContext7Widget() are then auto-imported.
npm install @desource/context7-widget-svelte<script lang="ts">
import { Context7Widget } from '@desource/context7-widget-svelte';
import '@desource/context7-widget-svelte/styles.css';
let open = $state(false);
</script>
<Context7Widget bind:open library="/owner/repo" position="anchor" preset="glass" customTrigger />npm install @desource/context7-widget-angularimport { Context7Widget } from '@desource/context7-widget-angular';
@Component({
standalone: true,
imports: [Context7Widget],
template: '<context7-widget library="/owner/repo" position="anchor" preset="glass" [customTrigger]="true" />'
})
export class DocsAssistant {}Import @desource/context7-widget-angular/styles.css once in the application stylesheet or build configuration.
- Official-compatible script replacement for the fastest migration path.
- Fixed corners, centered dialog, backdrop, and trigger-anchored positioning.
- Presets:
default,minimal,glass,neo,terminal, andbrutalist. - Theme modes:
light,dark, andauto. - Preset-owned action colors when
coloris omitted. - Custom triggers by selector, including anchored popovers.
- Typed DOM events for questions, streaming answers, tool calls, errors, and lifecycle state.
- Race-safe cancellation with a visible Stop action and imperative
cancel/retry/resetcontrols. - Multiline input, answer/code copying with repeat-click protection, error retry, complete UI localization, safe relative links, tables, task/nested lists, blockquotes, and highlighted code.
- Frame-throttled plain-text streaming that defers Markdown parsing until an answer completes, avoiding quadratic reparsing while long answers stream.
- Centered-dialog background isolation and scroll locking, focus containment, safe-area padding, and contained message scrolling.
- Public CSS variables and stable shadow parts for product-grade styling.
- Native Vue, React, Svelte, and Angular renderers with idiomatic controlled state, framework-native controls, managed triggers, and the same parameterized unit/browser contracts.
- Nuxt 3/4 module with component and composable auto-imports, app defaults, and optional global CSS.
- Daily upstream scanner for the official unversioned Context7 widget script.
The core widget is a shadow-DOM custom element. Style it through the public contract:
- CSS variables on
context7-widget ::part(...)selectors for stable internal blockswidget-idfor per-instance scoping- presets as a starting point, not a design limit
context7-widget[widget-id='docs'] {
--c7-accent: #7cffb2;
--c7-accent-contrast: #07120c;
--c7-font-family: Inter, ui-sans-serif, system-ui, sans-serif;
--c7-panel-background: #101513;
--c7-panel-color: #f7f2e8;
--c7-border-color: rgba(247, 242, 232, 0.18);
--c7-panel-radius: 8px;
}
context7-widget::part(send-button) {
min-width: 5rem;
text-transform: uppercase;
}Native Vue, React, Svelte, and Angular packages render light DOM. Apply the
same variables to .context7-widget; their package guides document the
framework-specific trigger selector and customization examples.
See the live customization guide and integration examples.
Common script attributes and component props:
librarythemepresetpositioncolorcustomTriggerbackdropcloseOnOutsideClickdefaultOpeninitialMessagelabelslauncherLabellauncherVariantlinkBaseUrlpanelHeightpanelWidthplaceholdertitlewidgetId
The host element dispatches composed DOM events:
c7:readyc7:openc7:closec7:cancelc7:questionc7:first-tokenc7:answerc7:answer-completec7:tool-callc7:tool-resultc7:error
Cancelling after answer tokens arrive preserves the visible partial assistant
message in getMessages() with status: 'cancelled'.
Example:
document.addEventListener('c7:question', (event) => {
analytics.track('Docs question', {
library: event.detail.library,
question: event.detail.question,
widgetId: event.detail.widgetId
});
});- Core package
- Vue package
- Nuxt package
- React package
- Svelte package
- Angular package
- Integration recipes
- Architecture notes
- Contributing guide
- Release process
- Security policy
pnpm install
pnpm lint
pnpm build
pnpm test:unit
pnpm test:e2e
pnpm dev:prepare
pnpm dev:demoThe packages use framework-appropriate production builders. The demo site
builds every package, copies packages/core/dist/widget.js into
demo/public/widget.js, then runs Nuxt.
The manually dispatched CI workflow and mandatory release gate enforce coverage
floors, production dependency and peer checks, package metadata/type
validation, SSR imports, and gzip budgets for the hosted widget and real
tree-shaken consumers of core, /core, /kit, every framework package, and
their stylesheets. Core, Vue, React, Svelte, and Angular run the same behavior
suite in desktop Chromium, Firefox, WebKit, and mobile WebKit profiles; Nuxt
adds module fixtures covering SSR, generated types, and disabled integrations.
The scheduled scanner downloads https://context7.com/widget.js, stores a raw
snapshot, normalized copy, metadata, and SHA-256 hash under upstream/, then
opens a GitHub issue when the official script changes.
That scanner watches client-script drift. Runtime answers still depend on the Context7 hosted backend, so manual smoke testing remains part of release work.
This repo uses Changesets for npm releases. Public package changes should include:
pnpm changesetMaintainers publish through the workflow documented in RELEASE.md.