Skip to main content

Intent System

Overview

The Intent System is a foundational feature of CommonPlace that requires every post to carry an explicit intent signal before it can be published. Rather than leaving readers to guess the author's tone or purpose, the intent system provides upfront context about how a post should be received.

There are exactly six intent types, each with a distinct emoji, label, description, and color scheme. The intent is selected before any content is written, making it the first decision a user makes when composing. This "intent-first" design prevents the platform from becoming an undifferentiated stream of content and helps readers calibrate their responses appropriately.

The intent system also supports per-intent visual customization. Each user can configure different fonts, surfaces, frames, and even avatars for each intent type, giving their posts a consistent visual identity tied to the kind of sharing they are doing.

Relevant Invariants

  • Invariant #4: "Intent Precedes Interpretation" -- Every post carries an intent signal chosen by the author before writing, ensuring readers have context before reacting.
  • Invariant #6: "No Public Comparative Metrics" -- Intents are informational labels, never ranked, scored, or compared against each other.
  • Invariant #17: "AI Doesn't Compete with Humans" -- The intent system is entirely user-driven; no AI suggests or auto-assigns intents.

User Experience

User Flow

  1. When the user opens the composer (either quick or advanced), the first thing they see is the intent selection prompt: "How should this be received?"
  2. The user selects one of six intent pills, each displayed with its emoji and label.
  3. On selection, the compose area transforms to reflect the selected intent's color scheme and any saved per-intent style (font, surface, effects).
  4. The user writes their content within the styled frame.
  5. The intent badge appears on the published post as a small indicator overlapping the author's avatar in the corner of the post card.
  6. Readers see the intent emoji and can hover/tap for the full label, immediately understanding the author's purpose.

The Six Intents

Intent KeyEmojiLabelDescription
thinking_out_loud💭Thinking AloudProcessing thoughts out loud. Not necessarily looking for solutions.
open_to_discussion💬Invite to DiscussThe author welcomes different perspectives on this.
sharing_personal:white_heart:Personal ShareSomething personal. Handle with care.
asking_for_help:hand_raised:Asking for HelpLooking for advice, support, or practical help.
just_for_fun😀Just for FunLighthearted -- just sharing for the joy of it.
sharing_information📌Offering ResourceSharing something useful -- an article, tool, idea, or recommendation.

Technical Implementation

Key Files

FilePurpose
src/lib/constants/intents.jsCanonical single source of truth for all 6 intent definitions, CSS mappings, and lookup helpers
src/components/post-parts/IntentBadge.jsxRenders the corner avatar + intent indicator overlay on post cards
src/hooks/useIntentStyles.jsFetches per-user intent styles (font, frame, surface, effects, avatar) for viewing and editing
src/components/CreatePost.jsxQuick composer with intent-first selection phase
src/components/AdvancedComposer.jsxFull editor with intent selection, per-intent style loading, and style presets

Data Model

The INTENT_OPTIONS array defines each intent with id, emoji, label, and description. The INTENT_CSS_MAP maps each intent key to a shorter CSS key used for CSS custom property names (e.g., thinking_out_loud maps to thinking).

CSS custom properties follow the pattern --intent-{cssKey}-{property}, for example:

  • --intent-thinking-accent
  • --intent-discussion-bg-tint
  • --intent-personal-border

Database Tables

TablePurpose
intent_stylesStores per-user, per-intent visual customizations (font, frame, surface, effects, avatar_url, photo_url, background_image_url)
user_intent_stylesStores style preferences saved from the Advanced Composer (surface, texture, font, emphasis)
style_presetsNamed style presets that users can save and reuse across intents

Hooks API

useIntentStyles(userId) -- Returns { styles, loading } where styles is a map of intent key to style object for viewing another user's posts.

useMyIntentStyles() -- Returns { styles, loading, updateStyle, updatePhoto, user } for the current user to read and modify their own intent styles. Uses upsert on intent_styles with conflict resolution on (user_id, intent).

Lookup Helpers

  • getIntentById(id) -- Returns the full intent object for a given key
  • getIntentEmoji(id) -- Returns the emoji for a given intent key
  • getIntentLabel(id) -- Returns the display label
  • getIntentCssKey(id) -- Returns the shortened CSS key

Edge Cases

ScenarioBehavior
No intent selectedPost button is disabled; user cannot publish without choosing an intent
User changes intent mid-composeCompose frame re-styles to match the new intent; content is preserved
Author has no saved style for an intentDefault style is used: system font, flat frame, light surface, no effects, normal emphasis
Intent badge on shared postsThe original post's intent is displayed, not the sharer's
Viewing posts from users with custom stylesThe author's intent_styles are fetched and applied per-post in the feed
  • Posts -- Post creation uses the intent system as its first step
  • Advanced Composer -- Full editor with per-intent style customization
  • Feed -- Feed renders posts with per-author intent styles

Last updated: 2026-02-07