Mark html tags with a unique identifier and generate a JSON file with the mapping.
npm install @nuasite/cms-markerAn Astro integration that automatically marks HTML elements with unique identifiers and generates a manifest mapping content to source files and line numbers. Perfect for building CMS editors that need to track where content originates in your codebase.
- Automatic Marking: Adds data-cms-id attributes to HTML elements during build
- Source Location Tracking: Maps content back to exact line numbers in .astro source files
- Variable Detection: Finds content defined as variables in frontmatter
- Nested Content Support: Handles placeholders for nested CMS-editable elements
- Dev & Build Modes: Works in both development and production builds
- Manifest Generation: Creates JSON manifest with all CMS-editable content
``bash`
bun add -D @nuasite/cms-markeror: npm install -D @nuasite/cms-marker
Add the integration to your astro.config.mjs:
`js
import cmsMarker from '@nuasite/cms-marker'
import { defineConfig } from 'astro/config'
export default defineConfig({
integrations: [
cmsMarker({
// Optional configuration
attributeName: 'data-cms-id',
includeTags: null, // null = all tags, or specify array like ['h1', 'p', 'a']
excludeTags: ['html', 'head', 'body', 'script', 'style'],
includeEmptyText: false,
}),
],
})
`
The integration processes your HTML and adds unique IDs:
` This is some contenthtmlWelcome to my site
This is some content
$3
It searches your
.astro source files to find where content originates:`astro
---
const title = "Welcome to my site";
---
{title}
`$3
Creates a JSON manifest mapping IDs to source locations:
`json
{
"cms-0": {
"id": "cms-0",
"file": "index.html",
"tag": "h1",
"text": "Welcome to my site",
"sourcePath": "src/components/Hero.astro",
"sourceLine": 4
}
}
`Configuration Options
$3
- Type:
string
- Default: 'data-cms-id'
- The HTML attribute name to use for marking elements.$3
- Type:
string[] | null
- Default: null
- If null, all tags are included. Otherwise, only specified tags are marked.$3
- Type:
string[]
- Default: ['html', 'head', 'body', 'script', 'style']
- Tags to exclude from marking.$3
- Type:
boolean
- Default: false
- Whether to mark elements with no text content.Manifest Entry Structure
Each entry in the manifest contains:
`typescript
export interface ManifestEntry {
id: string // The CMS ID (e.g., "cms-0")
file: string // Output HTML file (e.g., "index.html")
tag: string // HTML tag name (e.g., "h1")
text: string // Text content with placeholders for nested elements
sourcePath?: string // Source .astro file path
sourceLine?: number // Line number in source file
sourceSnippet?: string // Source code snippet
sourceType?: 'static' | 'variable' | 'prop' | 'computed' // Type of source
variableName?: string // Variable name if source is a variable
childCmsIds?: string[] // IDs of nested CMS elements
}
`Supported Patterns
$3
`astro
Hello World
`$3
`astro
---
const title = "My Title";
---
{title}
`$3
`astro
---
const path: string = "src/pages";
---
{path}
`$3
`astro
---
const content = {
title: "Welcome",
subtitle: "Get Started"
};
---
{content.title}
{content.subtitle}
`$3
`astro
Start nested end
`$3
`astro
---
const text = 'What\'s up';
const message = "Hello & goodbye";
---
{text}
{message}
`$3
Some patterns have limited support and may not always resolve to exact source locations:
- Complex variable expressions
- Props passed from parent components
- Template literals with expressions
- Computed values
In these cases, the manifest will still include the entry but
sourceLine may be undefined.Development
`bash
Install dependencies
bun installRun tests
bun testRun tests in watch mode
bun test --watch
`Testing
The package includes comprehensive tests (27 tests, all passing) covering:
- HTML processing and ID assignment
- Tag inclusion/exclusion rules
- Manifest generation
- Source location finding
- Variable reference detection
- Escaped quotes and HTML entities
- Multiple identical tags disambiguation
- Edge cases and error handling
Run tests with:
`bash
bun test
`See
src/tests/` for all test cases.Contributions are welcome! Please feel free to submit issues and pull requests.