A Convex component for smart tagging and categorization with hierarchy and analytics
npm install convex-smart-tagsbash
npm install convex-smart-tags
or
yarn add convex-smart-tags
`
Quick start
1. Add the component to your Convex app configuration:
`ts
// convex/convex.config.ts
import { defineApp } from "convex/server";
import smartTags from "convex-smart-tags/convex.config";
const app = defineApp();
app.use(smartTags);
export default app;
`
2. Use the client wrapper inside Convex functions:
`ts
// functions.ts (Convex server-side code)
import { SmartTags } from "convex-smart-tags";
import { components } from "./_generated/api";
import { mutation, query } from "./_generated/server";
const smartTags = new SmartTags(components.smartTags);
export const tagPost = mutation({
handler: async (ctx) => {
const postId = "post123";
await smartTags.addTag(ctx, {
tagName: "urgent",
tableName: "posts",
entityId: postId,
});
},
});
export const getPostTags = query({
args: { postId: v.id("posts") },
handler: async (ctx, args) => {
return smartTags.getTagsForEntity(ctx, {
tableName: "posts",
entityId: args.postId,
});
},
});
`
See the example/ directory for a complete working example application.
API overview
The component exposes a client wrapper SmartTags with a type-safe surface. Primary methods include:
- addTag(ctx, args: { tagName, tableName, entityId }): Promise
- removeTag(ctx, args: { tagName, tableName, entityId }): Promise
- getTagsForEntity(ctx, args: { tableName, entityId }): Promise>
- getEntitiesByTag(ctx, args: { tagName, tableName?, limit? }): Promise>
- createTagHierarchy(ctx, args: { parentTag, childTag }): Promise
- getChildTags(ctx, args: { parentTag, limit? }): Promise>
- getTagAncestors(ctx, args: { tagName }): Promise>
- getTrendingTags(ctx, args: { timeRange, limit? }): Promise>
- getTagStats(ctx, args: { tagName }): Promise<{ totalUsage, entityCount, createdAt, recentTrend }>
- getTagsAcrossTables(ctx, args?: { limit? }): Promise>
Each method is implemented in a type-safe manner; consult the generated types under src/_generated in your project for full signatures.
Schema
The component registers the following tables in your Convex schema:
- tags
- name: string
- createdAt: number
- usageCount: number
- indexed by: by_name
- entityTags
- tagName: string
- tableName: string
- entityId: string
- createdAt: number
- indexes: by_tag, by_entity, by_tag_and_entity
- tagHierarchy
- parentTag: string
- childTag: string
- createdAt: number
- indexes: by_parent, by_child, by_parent_and_child
- tagAnalytics
- tagName: string
- usageDate: number
- dailyCount: number
The full schema definition is in src/component/schema.ts.
Examples
Basic tag management:
`ts
// Add a tag to an entity
await smartTags.addTag(ctx, {
tagName: "important",
tableName: "posts",
entityId: "post123",
});
// Get tags for an entity
const tags = await smartTags.getTagsForEntity(ctx, {
tableName: "posts",
entityId: "post123",
});
`
Tag hierarchy:
`ts
// Create a parent-child relationship
await smartTags.createTagHierarchy(ctx, {
parentTag: "technology",
childTag: "ai",
});
// Get child tags
const children = await smartTags.getChildTags(ctx, { parentTag: "technology" });
// Get ancestor chain
const ancestors = await smartTags.getTagAncestors(ctx, { tagName: "ai" });
`
Analytics and trending:
`ts
// Get trending tags for the last 7 days
const sevenDays = 7 24 60 60 1000;
const trending = await smartTags.getTrendingTags(ctx, {
timeRange: sevenDays,
limit: 10,
});
// Get comprehensive statistics for a single tag
const stats = await smartTags.getTagStats(ctx, { tagName: "ai" });
`
Example Convex component registration (from example/convex/convex.config.ts):
`ts
import { defineApp } from "convex/server";
import smartTags from "convex-smart-tags/convex.config";
const app = defineApp();
app.use(smartTags);
export default app;
`
Testing
The package includes test helper registration for the Convex test environment.
`ts
// src/test.ts — usage inside tests
import { convextTest } from "convex-test";
import smartTagsTest from "convex-smart-tags/src/test";
const t = convextTest();
smartTagsTest.register(t, "smartTags");
`
Run the project's test and typecheck commands as configured (see vitest.config.js and package.json scripts).
Development
To develop locally:
1. Install dependencies
`bash
npm install
`
2. Build and run example
`bash
npm run build
cd example
npm install
npx convex dev
npm run dev
`
3. Typecheck and run tests
`bash
npm run typecheck
npm run test
`
License
Apache-2.0 — see the LICENSE` file for details.