# Dewemoji User Flow & UX Brief **Version:** 1.0 **Date:** February 8, 2026 **Purpose:** Define seamless user experience across visitor → logged → paid states **Related Doc:** dewemoji-direction-2026.md --- ## Executive Summary Dewemoji implements a **hybrid quick-add flow** where Personal users can add keywords instantly from emoji detail pages (80% of use cases) while maintaining full CRUD power in the dashboard (20% management). This creates a frictionless progression: discovery → personalization → habit, without disrupting the free user experience. **Core UX Principle:** *"Add keywords where you discover emojis, manage them where you organize."* --- ## 1. User State Definitions ### 1.1 Visitor (Non-Logged) **Who:** Anyone landing on dewemoji.com or using Chrome extension (no account) **Intent:** Quick emoji search and usage **Experience:** Zero friction, no login walls ### 1.2 Free User (Logged, No Subscription) **Who:** Registered account, free tier **Intent:** Exploring Personal features, considering upgrade **Experience:** Full free features + gentle upgrade hints ### 1.3 Personal User (Logged, Paid) **Who:** Active Personal subscription ($4.99/mo, $49/yr, or $99 lifetime) **Intent:** Building and syncing personal keyword library **Experience:** Full personalization power across all touchpoints --- ## 2. Primary User Flows ### 2.1 Discovery Flow (All Users) ``` User lands on dewemoji.com ↓ Search bar: "bekicot" ↓ Results page: 🐌 snail (public keywords: "snail, escargot") ↓ Click emoji → Detail page ↓ [State-dependent experience - see Section 3] ``` **Key Insight:** All users start here. Free discovery hooks them; Personal lets them own it. --- ### 2.2 Personalization Flow (Personal Users) #### Primary: Quick Add from Detail Page (80% Usage) ``` Personal user searches "snail" ↓ Detail page shows: ┌─────────────────────────────────────┐ │ 🐌 Snail │ │ │ │ Public Keywords: snail, escargot │ │ │ │ Your Keywords: (none yet) │ │ [+ Add Your Keyword] │ └─────────────────────────────────────┘ ↓ User clicks [+ Add Your Keyword] ↓ Inline modal appears: ┌─────────────────────────────────────┐ │ What do you call this emoji? │ │ ┌─────────────────────────────────┐│ │ │ bekicot, siput ││ │ └─────────────────────────────────┘│ │ Language: [Indonesian ▾] │ │ [Cancel] [Save Keyword] │ └─────────────────────────────────────┘ ↓ Saves instantly → Toast: "Added 'bekicot' to your library ✓" ↓ Detail page now shows: ┌─────────────────────────────────────┐ │ 🐌 Snail │ │ │ │ Public Keywords: snail, escargot │ │ │ │ Your Keywords: │ │ • bekicot (ID) [edit] [×] │ │ • siput (ID) [edit] [×] │ │ [+ Add Another] │ └─────────────────────────────────────┘ ↓ Next search: "bekicot" → 🐌 appears in results! ``` **Why This Flow:** - **Contextual:** User is *already looking at* the emoji they want to name - **Fast:** 2 clicks (add button → save), ~5 seconds total - **Immediate gratification:** See change instantly in searches - **Low friction:** No navigation away from discovery flow --- #### Secondary: Dashboard Management (20% Usage) **When Used:** - Bulk editing/organizing keywords - Reviewing all keywords at once - Exporting/importing keyword libraries - Fixing typos across multiple entries ``` User navigates to Dashboard → My Keywords tab ↓ Table view: ┌───────────────────────────────────────────────────────────┐ │ Emoji | Your Keywords | Lang | Actions │ ├───────────────────────────────────────────────────────────┤ │ 🐌 | bekicot, siput | ID | [Edit] [Delete] │ │ 😊 | senyum, happy | ID | [Edit] [Delete] │ │ 🔥 | api, fire, lit | ID | [Edit] [Delete] │ └───────────────────────────────────────────────────────────┘ [+ Add Keyword] [Import JSON] [Export JSON] [Search/Filter] ↓ User clicks [+ Add Keyword] ↓ Modal: Search emoji picker → Select 🎉 → Add keywords ↓ Saves to table → Auto-sync to extension ``` **Why Dashboard Exists:** - Power users want bulk operations - Easy to review/audit entire library - Import/export for backup - Edit mistakes without finding emoji again --- ### 2.3 Upgrade Flow (Free → Personal) #### Trigger Points **1. On Detail Page (Soft Prompt)** ``` Free user on emoji detail page sees: ┌─────────────────────────────────────┐ │ 🐌 Snail │ │ │ │ Public Keywords: snail, escargot │ │ │ │ 💎 Want to add your own keywords? │ │ like 'bekicot' or 'siput'? │ │ [Upgrade to Personal →] │ └─────────────────────────────────────┘ ``` **2. On Search Miss (Strong Prompt)** ``` User searches "bekicot" → No results ↓ Results page shows: ┌─────────────────────────────────────┐ │ No results for "bekicot" │ │ │ │ 💡 With Personal, you can create │ │ "bekicot → 🐌" and sync it │ │ everywhere. │ │ [Try Personal Free for 7 Days] │ └─────────────────────────────────────┘ ``` **3. From Extension (Contextual)** ``` Extension user searches "bekicot" → Not found ↓ Extension shows inline banner: "Add 'bekicot' to your library with Personal" [Upgrade] button → Opens dewemoji.com/upgrade ``` **4. From Dashboard (Clear Path)** ``` Free user clicks "My Keywords" tab ↓ Shows empty state: ┌─────────────────────────────────────┐ │ 📚 Your Personal Keyword Library │ │ │ │ You have 0 keywords. │ │ │ │ Upgrade to Personal to: │ │ ✓ Add unlimited keywords │ │ ✓ Search in your language │ │ ✓ Sync across all devices │ │ │ │ [Start 7-Day Free Trial] │ └─────────────────────────────────────┘ ``` --- ## 3. State-Dependent UI Elements ### 3.1 Emoji Detail Page #### Visitor (Non-Logged) ```html

🐌 Snail

Keywords

💡 Want to search in your language?

``` #### Free User (Logged) ```html

🐌 Snail

Keywords

Your Keywords

💎 Add personal keywords like 'bekicot'

``` #### Personal User (Logged + Paid) ```html

🐌 Snail

Public Keywords

Your Keywords

What do you call this emoji?

``` --- ### 3.2 Search Results Page #### All Users (Public Results) ```html
🐌 Snail snail
``` #### Personal User (Blended Results) ```html
🐌 Snail bekicot Your keyword
🐌 Snail snail
``` --- ### 3.3 Dashboard (Personal Users Only) ```html
Emoji Your Keywords Language Actions
🐌 bekicot, siput ID
``` --- ## 4. API Endpoints for UX Flows ### 4.1 Detail Page Quick Add **Fetch user's keywords for specific emoji:** ``` GET /v1/emoji/:slug?include_user_keywords=true Authorization: Bearer dew_abc123... Response: { "emoji": {...}, "public_keywords": ["snail", "escargot"], "user_keywords": [ {"id": "uk_1", "keyword": "bekicot", "lang": "id"}, {"id": "uk_2", "keyword": "siput", "lang": "id"} ] } ``` **Add keyword from detail page:** ``` POST /v1/keywords/quick Authorization: Bearer dew_abc123... Body: { "emoji_slug": "snail", "keywords": ["bekicot", "siput"], "lang": "id" } Response: { "success": true, "added": ["bekicot", "siput"], "emoji_slug": "snail" } ``` **Edit single keyword:** ``` PATCH /v1/keywords/:id Authorization: Bearer dew_abc123... Body: { "keyword": "bekicot kecil" } ``` **Delete keyword:** ``` DELETE /v1/keywords/:id Authorization: Bearer dew_abc123... ``` --- ### 4.2 Dashboard Bulk Operations **List all user keywords:** ``` GET /v1/keywords?page=1&limit=50 Authorization: Bearer dew_abc123... Response: { "keywords": [ { "id": "uk_1", "emoji_slug": "snail", "emoji": "🐌", "keyword": "bekicot", "lang": "id", "created_at": "2026-02-08T10:30:00Z" } // ... more ], "total": 47, "page": 1 } ``` **Bulk import:** ``` POST /v1/keywords/import Authorization: Bearer dew_abc123... Body: { "keywords": [ {"emoji_slug": "snail", "keywords": ["bekicot"], "lang": "id"}, {"emoji_slug": "fire", "keywords": ["api"], "lang": "id"} ] } Response: { "imported": 2, "skipped": 0, "errors": [] } ``` **Export:** ``` GET /v1/keywords/export?format=json Authorization: Bearer dew_abc123... Response: (Download JSON file) ``` --- ## 5. Frontend Implementation Specs ### 5.1 Emoji Detail Page Changes **File:** `/pages/emoji/[slug].js` (or equivalent) **Required Elements:** 1. **User keywords section** (Personal only) - Fetch on page load: `GET /v1/emoji/:slug?include_user_keywords=true` - Show list of user's keywords with edit/delete buttons - Show "Add Keyword" button 2. **Add keyword modal** - Input: comma-separated keywords - Dropdown: language selector (EN, ID, KO, JA, etc.) - Save button → POST `/v1/keywords/quick` - Success → update UI without page reload 3. **Inline edit** - Click "edit" → input becomes editable - Save → PATCH `/v1/keywords/:id` - Cancel → revert 4. **Inline delete** - Click "×" → confirm modal - Yes → DELETE `/v1/keywords/:id` → remove from UI **State Management:** ```javascript const [userKeywords, setUserKeywords] = useState([]); const [isPersonal, setIsPersonal] = useState(false); // On mount useEffect(() => { if (user?.tier === 'personal') { fetchUserKeywords(emojiSlug); } }, [emojiSlug, user]); // Add keyword const handleAddKeyword = async (keywords, lang) => { const result = await api.post('/keywords/quick', { emoji_slug: emojiSlug, keywords: keywords.split(',').map(k => k.trim()), lang }); if (result.success) { fetchUserKeywords(emojiSlug); // Refresh list toast.success('Keywords added!'); } }; ``` --- ### 5.2 Dashboard Implementation **File:** `/pages/dashboard.js` **Tabs:** 1. My Keywords (default) 2. API Keys 3. Billing **My Keywords Tab Components:** ```javascript // Main table component // Toolbar actions // Add keyword modal (with emoji picker) ``` **Features:** - Pagination (50 per page) - Search/filter by keyword or emoji - Bulk select + delete - Sort by: date added, emoji name, language --- ### 5.3 Upgrade Flow Pages **File:** `/pages/upgrade.js` or `/pages/pricing.js` **Components:** 1. **Feature comparison table** ```html
Feature Free Personal
Public emoji search ✅ Unlimited ✅ Unlimited
Private keywords ✅ Unlimited
``` 2. **Pricing cards** ```html

Monthly

$4.99/mo

Lifetime

$99 once

``` 3. **Stripe checkout integration** ```javascript const handleCheckout = async (plan) => { const session = await api.post('/stripe/checkout', { plan, // 'monthly' | 'annual' | 'lifetime' success_url: `${baseUrl}/dashboard?upgraded=true`, cancel_url: `${baseUrl}/upgrade` }); window.location.href = session.url; }; ``` --- ## 6. UX Copy & Messaging ### 6.1 Upgrade Prompts **Soft (Detail Page):** > 💡 Want to search in your language? Add personal keywords like 'bekicot' for 🐌 > [Upgrade to Personal →] **Strong (Search Miss):** > No results for "bekicot" > > 💎 **Create your own keywords with Personal** > Add "bekicot → 🐌" and sync it across all devices > [Try Free for 7 Days] **Empty State (Dashboard):** > 📚 **Your Personal Keyword Library** > > You have 0 keywords. > > Upgrade to Personal to: > ✓ Add unlimited keywords > ✓ Search in your language > ✓ Sync across all devices > > [Start 7-Day Free Trial] --- ### 6.2 Success Messages **After adding keyword:** > ✓ Added "bekicot" to your library **After editing:** > ✓ Keyword updated **After deleting:** > ✓ Keyword removed **After upgrade:** > 🎉 Welcome to Personal! Start adding your keywords. --- ### 6.3 Error Messages **Duplicate keyword:** > ⚠️ You already have "bekicot" for this emoji **Network error:** > ❌ Couldn't save. Check your connection and try again. **Unauthorized:** > 🔒 Please log in to add personal keywords --- ## 7. Mobile Considerations ### 7.1 Detail Page on Mobile - Add keyword button: **sticky bottom bar** (always visible) - Modal: **full-screen** on mobile (easier typing) - Keyword list: **swipeable cards** (swipe left to delete) ### 7.2 Dashboard on Mobile - Tabs: **horizontal scroll** or bottom nav - Table: **card view** (stack columns vertically) - Actions: **swipe gestures** (edit/delete) --- ## 8. Performance & Optimization ### 8.1 Caching Strategy **Client-side:** - Cache user keywords in localStorage/sessionStorage - Only refetch when: - User adds/edits/deletes - Page reload after 5 minutes **API-side:** - ETag support (already implemented) - Cache user keywords per user_id (Redis) - Invalidate on mutation ### 8.2 Loading States **Detail page:** ``` Loading user keywords... └─ Skeleton: [▯▯▯▯] [▯▯▯] [▯▯▯▯▯] ``` **Dashboard:** ``` Loading your library... └─ Table skeleton (5 rows) ``` --- ## 9. Analytics & Tracking ### Key Events to Track **Discovery:** - `emoji_viewed` (slug, user_tier) - `public_search` (query, has_results) - `search_miss` (query) → upgrade opportunity **Personalization:** - `keyword_added` (method: 'quick_add' | 'dashboard') - `keyword_edited` - `keyword_deleted` - `keywords_exported` **Conversion:** - `upgrade_prompt_shown` (location: 'detail' | 'search' | 'dashboard') - `upgrade_clicked` (location) - `trial_started` - `subscription_created` (plan: 'monthly' | 'annual' | 'lifetime') **Usage:** - `private_keyword_searched` (query, has_results) - `extension_synced` (keyword_count) --- ## 10. Testing Checklist ### 10.1 User State Tests - [ ] Visitor can search and view emoji details (no login) - [ ] Visitor sees upgrade CTA (non-intrusive) - [ ] Free user sees muted keyword section - [ ] Free user can't add keywords without upgrade - [ ] Personal user sees active keyword section - [ ] Personal user can add keywords from detail page - [ ] Personal user can edit/delete keywords inline ### 10.2 Flow Tests - [ ] Quick add: add keyword → appears in list immediately - [ ] Quick add: new keyword searchable instantly - [ ] Dashboard: bulk add works correctly - [ ] Dashboard: export downloads valid JSON - [ ] Dashboard: import restores keywords - [ ] Search: private keywords appear first in results - [ ] Search: private keywords have "Your keyword" badge ### 10.3 Edge Cases - [ ] Add duplicate keyword → shows error - [ ] Delete last keyword for emoji → removes emoji from search - [ ] Offline: queue mutations, sync when online - [ ] Rate limit: show friendly error - [ ] API error: show retry option --- ## 11. Implementation Priority ### Phase 1: Detail Page Quick Add (Week 1) 1. Add user keywords section to detail page 2. Build add keyword modal 3. Implement POST /keywords/quick endpoint 4. Add inline edit/delete ### Phase 2: Search Blending (Week 1) 1. Update search to blend private + public 2. Add "Your keyword" badge to results 3. Show private matches first ### Phase 3: Dashboard (Week 2) 1. Build My Keywords tab with table 2. Add bulk actions (import/export) 3. Implement search/filter ### Phase 4: Upgrade Flow (Week 2) 1. Build upgrade prompts (detail, search miss, dashboard) 2. Create pricing page 3. Integrate Stripe checkout --- ## 12. Open Questions & Future Enhancements 1. **Keyword suggestions:** Should we suggest keywords based on emoji name/category? 2. **Keyboard shortcuts:** Quick add keyword with hotkey (Ctrl+K)? 3. **Recently added:** Show "Recently added keywords" widget on dashboard? 4. **Keyword collections:** Group keywords by category/theme? 5. **Sharing:** Allow users to share their keyword libraries with friends? --- **End of UX Brief** This document defines the seamless user experience for Dewemoji's core value proposition: instant, contextual personalization. Implementation should prioritize the detail page quick-add flow (80% of usage) while building dashboard for power users (20%).