Skip to content

Repository files navigation

Can It!

Can It! is a browser-based canned-response library. Create reusable message templates, mark variable details with {{placeholders}}, fill those details when using a response, and copy the completed message to the clipboard.

The application runs entirely in the browser. Responses are stored locally in IndexedDB; no server, account, or network connection is required.

Features

  • Create, edit, search, and delete canned responses.
  • Define placeholders directly in template text, for example Hi {{first name}}.
  • Configure each placeholder as text, integer, or a choice list, with required and default-value settings.
  • Fill placeholders inline and preview the completed response before copying it.
  • Export the complete library to JSON and import it later by merging or replacing local data.
  • Ask the browser to keep local storage persistent, reducing the chance that it is cleared under storage pressure.

Architecture

The web app is a Vue 3 single-page application built with Vite and TypeScript.

src/
├── main.ts                 App bootstrap: mounts Vue, router, and global styles
├── App.vue                 Application shell, import/export, and storage status
├── router.ts               Client-side routes
├── views/                  Response library, editor, use, and not-found screens
├── domain/                 Domain types and template/placeholder logic
├── data/                   Storage interface and IndexedDB implementation
└── state/                  Shared reactive application state

Presentation and navigation

App.vue provides the shared header, import/export controls, and browser-storage messaging. vue-router selects a view for each workflow:

Route Purpose
/ Browse and search saved responses
/responses/new Create a response
/responses/:responseId/edit Edit a response and its local placeholder configuration
/responses/:responseId/use Fill details, preview, and copy a response

Domain model

A response contains its template and its own placeholder configuration. Placeholder definitions are deliberately response-local rather than shared globally. Repeated tokens within the same template use the same value.

interface CannedResponse {
  id: string
  name: string
  body: string
  placeholders: PlaceholderConfig[]
  createdAt: string
  updatedAt: string
}

Template tokens use double braces: {{identifier}}. The domain helpers discover tokens, preserve existing configuration when a template changes, validate values, and resolve a completed template.

Data and state

The app depends on the DataStore interface in src/data/data-store.ts, which keeps views independent of the persistence mechanism. The current implementation, IndexedDbDataStore, uses Dexie to store response records in an IndexedDB database named can-it.

src/state/app-state.ts owns the shared reactive response collection and initialization state. It opens the data store during startup and refreshes the library after saves, deletes, and imports.

Local data and backups

All response data remains in the current browser profile and origin. Clearing browser site data, using a different browser/profile, or changing origins creates a separate library. Export regularly if the data matters to you.

Exports use this versioned shape:

{
  "format": "can-it-export",
  "version": 1,
  "exportedAt": "2026-08-23T00:00:00.000Z",
  "responses": []
}

Imports validate this format before writing data. A merge import adds or updates records by ID; a replace import clears the current response collection and writes the imported library in a single IndexedDB transaction.

Development

Prerequisites

  • Node.js 20.19.0 or newer
  • npm

Install and run

npm install
npm run dev

Vite prints the local development URL in the terminal. The application needs a modern browser with IndexedDB support.

Production build

npm run build
npm run preview

npm run build performs Vue/TypeScript checking with vue-tsc and writes the production bundle to dist/. npm run preview serves that bundle locally for verification.

Automated tests

The test suite has two layers:

  • Vitest unit and persistence tests cover template parsing and validation plus the real Dexie data store using an in-memory IndexedDB implementation.
  • Playwright runs browser journeys against the Vite app, including response creation, placeholder configuration, copying, search, deletion, and import validation.

Run the full suite with:

npm test

During day-to-day development, run just the fast tests with npm run test:unit (or npm run test:unit:watch). Generate a coverage report with npm run test:coverage. Before the first browser run on a machine, install Playwright's Chromium binary:

npx playwright install chromium

Run only the browser tests with npm run test:e2e.

Legacy PowerShell version

The old PowerShell version of this project is available in the PowerShell version release.

License

See LICENSE.

About

Can It! is a browser-based canned-response library

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Contributors

Languages