5.4 KiB
Template Forking / Remix Feature Plan
Overview
Allow users to import any community template as a starting point for their own design, with automatic attribution to the original creator baked into the Nostr event. Forks are discoverable — anyone can see a template's remix lineage — and the original creator gets notified via a Nostr mention when someone forks their work.
Complexity
Low–Moderate — Estimated 2–4 hours
How It Works
Forking Flow
- User clicks "Remix this design" on a community template card
- App imports the template payload into the editor (same as existing "Import" flow)
- When the user publishes their remixed version, the new event includes a reference to the original template event ID in its tags
- Original creator receives a Nostr notification (kind 1 mention) that their template was remixed
Nostr Event Tags for a Fork
Add two tags to the published kind 30078 event:
{
"tags": [
["e", "<original-event-id>", "<relay-hint>", "fork"],
["p", "<original-creator-pubkey>"]
]
}
["e", ..., "fork"]— marks this as a derivative work; the marker"fork"is a custom convention (Nostr allows arbitraryetag markers)["p", ...]— notifies the original creator; their client will surface this as a mention
Attribution Display
In the template detail view, show a "Forked from" row when a fork e-tag is present:
Forked from: [Alice's Spider-Man Wrap] by [email protected] →
Clicking the arrow navigates to the original template in the feed.
Key Components
1. Remix Button
Add "Remix this design" to the template card action menu alongside existing Import option. Visually distinguish it (⑃ fork icon) so users understand it's different from a plain import.
function remixTemplate(event) {
importDiscDesignFromPayload(event.content); // existing import function
state.community.forkSourceEventId = event.id;
state.community.forkSourcePubkey = event.pubkey;
showNotification('Template loaded — your remix will credit the original creator.');
}
2. Fork State
Track pending fork metadata in state so it can be attached at publish time:
// Add to state:
fork: {
sourceEventId: null, // event ID of the template being remixed
sourcePubkey: null, // pubkey of the original creator
}
Clear state.fork when the user starts a fresh project or imports without remixing.
3. Publish Hook
In the existing publish function, inject fork tags when state.fork.sourceEventId is set:
function buildPublishTags(existingTags) {
const tags = [...existingTags];
if (state.fork.sourceEventId) {
tags.push(['e', state.fork.sourceEventId, '', 'fork']);
tags.push(['p', state.fork.sourcePubkey]);
}
return tags;
}
4. Fork Detection on Render
When rendering a template detail card, check for a fork e-tag and fetch + display the
source template title and author:
function getForkSource(event) {
const tag = event.tags?.find(t => t[0] === 'e' && t[3] === 'fork');
return tag ? { eventId: tag[1], relayHint: tag[2] } : null;
}
5. Remix Count
In the community feed, a template's remix count = number of kind 30078 events that
reference it with a fork e-tag. This can be fetched lazily:
async function fetchRemixCount(eventId) {
const events = await queryRelays(relays, {
kinds: [30078],
'#e': [eventId],
}, { timeoutMs: 2000 });
return events.filter(e => e.tags.some(t => t[0] === 'e' && t[3] === 'fork')).length;
}
UI Changes
- Template card action menu: add "⑃ Remix this design" below "Import"
- Editor header: show "Remixing: [original title]" badge while fork state is active
- Editor header: "Clear remix" link to discard attribution and start fresh
- Template detail panel: "Forked from" row (when fork e-tag present)
- Template detail panel: "X remixes" count below reaction row
Performance Considerations
- Fork source lookup is a single relay query — run it lazily when the detail panel opens
- Remix count query can be skipped on initial feed load and fetched on hover/click
- No new relay subscriptions needed — reuses existing
queryRelays()helper
Limitations
- Fork attribution is opt-in convention — anyone can publish a derivative without tagging; this feature makes attribution easy but cannot enforce it
- Relay hints in the
etag are best-effort; original event may not be on all relays - No fork graph visualization (full lineage tree) — out of scope for initial version
Future Enhancements
- Fork tree visualization: show the full remix lineage of popular templates
- "See all remixes" panel on template detail
- Notify original creator via kind 1 DM or push notification service
- Attribution in exported PDF metadata
Testing Checklist
- "Remix this design" imports template content into editor correctly
- Fork state (
sourceEventId,sourcePubkey) is set after remix - Published event contains
["e", ..., "fork"]and["p", ...]tags - Fork state clears on new project / plain import
- "Remixing: [title]" badge shows in editor while fork is active
- "Clear remix" removes fork state and badge
- Template detail shows "Forked from" row when fork e-tag is present
- "Forked from" link navigates to source template in feed
- Remix count displays on template detail (fetched lazily)
- Publishing without remix produces no fork tags