Home
Get Startedwhat is rhyme? Your First App Sign Up

BlocksBlock Types [start] [init] [blocks]
ActionsDisplay Actions Input Actions Data Actions Flow Actions Understanding Actions
VariablesNaming Conventions Special Variables $variables
ValuesWorking with Text Text Number Switch Item Group Date Time Duration
ImagesBasics Displaying Images Image Sources
IconsBasics Icon Styling !icon select tool
ColorsColor Sets Sets Color Tool Dynamic Theme
FontsBasics Preview Fonts
TagsUnderstanding Tags Sounds
SoundsBeep Sounds Tap Sounds Event Sounds Slide Sounds

reference
Actions.10x1-image .12x1-image .16x9-image .1x1-image .1x2-image .1x3-image .1x4-image .1x6-image .1x8-image .2x1-image .2x3-image .3x1-image .3x2-image .4x1-image .4x3-image .4x5-image .5x4-image .6x1-image .6x9-image .8x1-image .a .account-signup .acknowledge .acknowledge-once .action-help .action-list .alt .announcement .app-frame .app-icon .app-iphone .app-laptop .app-navbar .app-tablet .aside .avatar .back .back-button .back-header .background-animated-gradient .background-color .background-gradient .background-image .background-video .banner-divider .bluesky .bottom-center .bottom-left .bottom-navbar .bottom-panel .bottom-right .brand-screen .btn .busy-button .button .button-bar .chat-incoming .chat-input .chat-outgoing .chat-typing .checkbox-field .chip .circle-button .circle-image .click .close-icon .color-input .color-palette .color-swatch .column .confetti .continue-button .copy-textbox .copyright .corner-banner .date-input .details .devfooter .dialog .dicebear-avatar .div .divider .divider-bar .edit-app .editor .enter .enter-date .enter-email .enter-family-name .enter-fullname .enter-given-name .enter-helptext .enter-number .enter-password .enter-phone .enter-text .enter-time .enterkey-effect .error-line .facebook .filler .fineprint .fixed-footer .font-sample .footer .footer-nav .full-panel .fullscreen-error .github .golden-image .goleft-effect .goto .goto-effect .gradient .grid .grid-cell .handwriting .header .help .hide .hide-in-progress .hover-over .hr .icon .icon-avatar .icon-button .icon-with-label .iframe .image .image-avatar .image-button .image-header .image-title .inbox-message .inbox-message-input .initials-avatar .input .instagram .left-panel .link .linkedin .list .list-item .live-search .lottie .megaicon .menu .menu-item .middle-center .middle-left .middle-right .mobile-app-view .navigation-bar .navto .number .option .overlay .paragraph .paragraph-text .password-field .password-panel .paste-background .pinpad-input .placeholder .popup .popup-screen .profile .progress-bar .progress-circle .progress-circle-with-value .qrcode .radio-field .rhappsody .rhyme-editor .rhyme-example .rhyme-live .rhyme-source .right-panel .row .run .screen .screen-background .search .select .select-field .set .shape-divider .show-in-progress .signature .signature-pad .sim-app .simulate .simulator .slider-input .spacer .span .spinner .splash-screen .stack .tagline .text .text-field .textarea .textbox-field .textbox-input .time-input .tint .tiptext .title .top-appbar .top-center .top-left .top-panel .top-right .turnstile .twitter .upload-csv .upload-file .upload-file-input .upload-image .upload-json .user-login .validate-email .value .video .video-banner .video-button .wait .when-load-complete .youtube .youtube-video +attachable +decorate +paste-image +paste-image +tint +when-close +when-load-complete account-ctx account-login account-logout account-signup action add add-days add-line add-row add-text add-weeks admin-login ai-auth ai-context ai-model ai-provider allow-dynamic-actions and app app-authorization app-colors app-context app-context-server app-data app-expires-on app-font app-golive-on app-host app-image app-mode app-name app-password app-private app-public app-sound appdev average background-image bluesky break browser-version build-app calculate capitalize character clear-acknowledgement clear-announcement clear-client clear-icons clear-image clear-images clear-inbox clear-profile close-menu color compile conditional confetti console-error console-info console-log console-var contains continue core-kv-get core-kv-put core-run corner-banner create-key create-table csv day-names days-between days-until decode-secret decrement decrypt default default-style delay delete delete-all-videos delete-app-data delete-app-image delete-appgroup delete-column delete-inbox-message delete-key delete-public-app-data delete-public-user-data delete-row delete-saved delete-user-data dir-action dir-actions dir-app dir-blocks dir-boot dir-build dir-clear dir-clear-inbox dir-compile dir-compiler dir-current dir-delay dir-delete-appgroup dir-delete-image dir-dev dir-edit dir-edit-block dir-files dir-help dir-hide dir-images dir-inbox dir-list-apps dir-list-groups dir-load dir-login dir-login-if-needed dir-logout dir-mock-date dir-new dir-new-appgroup dir-new-image dir-publish dir-regen-keys dir-secrets dir-send-inbox-message dir-set dir-sets dir-shell dir-show dir-source dir-source-default dir-status dir-users dir-who distance-between divide down-key dynamic-action dynamic-color-theme editor-login editor-onkey enable-shell-shortcut encrypt endconditional english ensure-email enter-date enter-email enter-family-name enter-fullname enter-given-name enter-helptext enter-key enter-number enter-password enter-phone enter-text enter-time equals error-line escape-key exit-module facebook fadein fadeout fake fake-date fake-table fake-time fill-column filter-group first-row font foreach forget fullscreen-error generate-app-key get-ip-location get-item-number get-location get-public-key get-recipe get-row github goto groq-ai-chat groq-models have hide host-call http-delete http-get http-post http-put icon if if-fail if-is-closed if-is-open if-success image increment init-all init-animation init-auth init-chat init-client init-compiler init-help init-images instagram is-appgroup-available is-date is-greater-than is-group is-item is-less-than is-number is-time is-valid-email is-valid-phone key last-row launch-module left-key length-of linkedin list-actions list-actionsets list-app-data list-app-images list-appgroups list-apps list-areas list-color-palettes list-colors list-compilers list-dynamic-actions list-fonts list-icons list-images list-inbox list-public-app-data list-public-user-data list-recipes list-saved list-secrets list-user-data list-videos load load-app load-app-data load-audio load-binary-file load-compiler load-json-file load-public-app-data load-public-user-data load-saved load-source load-text-file load-user-data logic loop lowercase manager-login max missing modulo month-names multiply my-approups new-app new-appgroup new-profile noop not not-equals on-incoming-chat-message on-notification open-browser open-browser-window open-menu openai-chat pause-audio person pick-random play-audio print print-error print-header profile protect-with-password proxy publish-bin publish-html publish-private random-between random-dice-roll random-digits random-row random-text random-uuid register-actionset reload remember remove-secret render-recipe repeat resend-send-email reset-client resize-image restore-profile resume return right-key round round-down round-up run save save-app-data save-app-image save-public-app-data save-public-user-data save-source save-user-data say schedule secret send-email send-notification send-to-inbox server-run set set-active-schedule set-ai-service set-animation set-announcement set-app-bin set-app-source set-app-title set-brand-color set-build-mode set-css-variable set-debug-ui set-default set-default-font set-dev-mode set-email-bcc set-email-body set-email-cc set-email-from set-email-service set-email-subject set-email-to set-groq-api-key set-http-body set-http-header set-http-timeout set-iconset set-image set-language set-message-body set-message-from set-message-subject set-mock-mode set-private-key set-public-key set-resend-api-key set-secret set-sound set-start-block set-target-ag set-target-aid set-video set-voice set-voice-language shield show slide-down slide-left slide-right slide-up slot sort-column sort-group sort-table source-block-list source-delete-block source-get-block source-join-blocks source-split-blocks source-update-block space-between-lines space-key spanish split-text stack stop-audio store-profile style su-account su-accounts su-platform subscribe subtract sync-time-to-server test test-owner-auth test-server timer-start timer-stop toggle-menu top-left twitter typed-getters-example unpack-row unshield unsubscribe up-key upload-app-image uppercase use use-modules user user-data user-login vardump varref varset vibrate wait waitfor when youtube
action setsunderstanding action sets acknowledgement actions AI announcements appgroup audio auth avatars background barcodes blog browser buttons calendar chat client clipboard color column compiler components config core CSS data datetime debug decorator directive divider editor editors effects email enter error events examples exec feedback fields file flow fonts footers form goto groq group headers help HTML HTTP icons if images inbox init input inputs interaction keys language layout lists localstorage location log logic logicfn loops math media menus messaging mock modifier modules navigation network notifications numbers openai overlays paragraph platform print profile progress publish random recipes resend resources rhyme row rows screens search secrets security selects server services shell shield sim social sounds source specialfx speech stacks styling system table test testing text upload users utilities utils validate validation variables video view voice
advanced/shell Variable Types Mock Values environment
Tools/shell Rhyme Editor /shell Playground

TutorialsYour App's Inbox

Resources
Rhappsody Platform Community Discord Server

© 2025 Rhappsody

Your App's Inbox

Learn how to build a messaging system that lets users communicate with your app through an intuitive inbox interface. This tutorial will show you how to create, manage, and display messages in your Rhyme app.

What You’ll Build

In this tutorial, you’ll create:

Prerequisites

Before starting this tutorial, you should understand:

Step 1: Understanding the Inbox System

Your app can have its own inbox where users send messages. This is perfect for:

The inbox system in Rhyme provides built-in actions to manage messages seamlessly.

Step 2: Setting Up the Basic Inbox

Let’s start by creating a simple inbox view:

start inbox-demo

# Display inbox header
.header
  .title "My App Inbox"
  .divider

# List inbox messages
list-inbox => messages
  if messages.length = 0
    .text "No messages yet" -muted
  else
    foreach messages => msg
      .inbox-message msg
    end
  end

Step 3: Creating a Message Input

Now let’s add a way for users to send messages:

# Message input form
.card
  .title "Send a Message"
  
  # Subject line
  .text-field => subject
    -label: "Subject"
    -required
  
  # Message body
  .textarea => body
    -label: "Your Message"
    -rows: 5
    -required
  
  # Send button
  .button "Send Message" => 
    if subject and body
      send-to-inbox -subject:subject -body:body
      notify "Message sent!"
      clear subject
      clear body
    else
      notify "Please fill in all fields" -error
    end

Step 4: Displaying Individual Messages

Let’s create a better message display component:

block inbox-message msg
  .card -clickable => 
    # Mark as read when clicked
    if not msg.read
      # Update read status logic here
    end
    
    # Message header
    .row
      .column
        .text msg.subject -bold
        .text msg.from -small -muted
      .column -right
        .text msg.timestamp -small
    end
    
    # Message preview
    .text msg.body -truncate:100
    
    # Action buttons
    .row -end
      .button "Reply" -text => 
        # Reply logic
      .button "Delete" -text -danger => 
        delete-inbox-message msg.id
        notify "Message deleted"

Step 5: Adding Search and Filter

Make your inbox more powerful with search:

# Search bar
.search => query
  -placeholder: "Search messages..."

# Filter buttons
.row
  .chip "All" -active:filter="all" => set filter to "all"
  .chip "Unread" -active:filter="unread" => set filter to "unread"
  .chip "Starred" -active:filter="starred" => set filter to "starred"

# Filtered message list
list-inbox => messages
  # Apply filters
  if query
    filter messages where subject contains query or body contains query
  end
  
  if filter = "unread"
    filter messages where not read
  elif filter = "starred"
    filter messages where starred
  end
  
  # Display filtered results
  foreach messages => msg
    .inbox-message msg
  end

Step 6: Real-time Updates

Keep your inbox fresh with automatic updates:

# Poll for new messages every 30 seconds
schedule every 30 seconds
  list-inbox => new-messages
  if new-messages.length > $message-count
    notify "You have new messages!"
    set $message-count to new-messages.length
  end
end

# Initial message count
list-inbox => messages
set $message-count to messages.length

Step 7: Advanced Features

Message Actions
block message-actions msg
  .row
    .icon-button !reply => 
      set $replying-to to msg
      show reply-dialog
    
    .icon-button !star => 
      toggle msg.starred
      save-inbox-update msg
    
    .icon-button !archive => 
      archive-message msg
      notify "Message archived"
    
    .icon-button !trash => 
      confirm "Delete this message?" => confirmed
        if confirmed
          delete-inbox-message msg.id
          notify "Message deleted"
        end
Reply Dialog
block reply-dialog
  .dialog
    .title "Reply to: " + $replying-to.subject
    
    .textarea => reply-body
      -label: "Your reply"
      -rows: 5
      -autofocus
    
    .row -end
      .button "Cancel" -text => 
        hide reply-dialog
        clear $replying-to
      
      .button "Send Reply" -primary => 
        send-to-inbox 
          -subject: "Re: " + $replying-to.subject
          -body: reply-body
          -replyTo: $replying-to.id
        notify "Reply sent!"
        hide reply-dialog
        clear $replying-to

Complete Example

Here’s a full inbox implementation:

start app-inbox

# State management
set $filter to "all"
set $search-query to ""

# Main inbox view
.container
  .header
    .row
      .title "Inbox"
      .spacer
      .button "Compose" -primary => show compose-dialog
    end
  
  # Search and filters
  .row
    .search => $search-query
      -placeholder: "Search messages..."
      -flex: 1
    
    .chip "All" -active:$filter="all" => set $filter to "all"
    .chip "Unread" -active:$filter="unread" => set $filter to "unread"
  end
  
  # Message list
  .divider
  
  list-inbox => messages
    # Apply search filter
    if $search-query
      filter messages where 
        subject contains $search-query or 
        body contains $search-query
    end
    
    # Apply status filter
    if $filter = "unread"
      filter messages where not read
    end
    
    # Display messages
    if messages.length = 0
      .empty-state
        .icon !inbox -size:3 -muted
        .text "No messages found" -muted
    else
      foreach messages => msg
        .message-item msg
      end
    end
  end

# Message item component
block message-item msg
  .card -hover => 
    show-message msg
    
    .row
      .column -flex:1
        .row
          .text msg.subject -bold
          if not msg.read
            .badge "New" -primary -small
          end
        end
        .text msg.from -small -muted
        .text msg.preview -small -truncate:80
      
      .column -right
        .text msg.date -small -muted
        .row
          .icon-button !star -small
          .icon-button !trash -small -danger => 
            delete-inbox-message msg.id
            notify "Message deleted"
        end
    end
  end

# Compose dialog
block compose-dialog
  .dialog -large
    .title "New Message"
    
    .text-field => subject
      -label: "Subject"
      -required
    
    .textarea => body
      -label: "Message"
      -rows: 10
      -required
    
    .row -end
      .button "Cancel" -text => hide compose-dialog
      .button "Send" -primary => 
        if subject and body
          send-to-inbox -subject:subject -body:body
          notify "Message sent successfully!"
          hide compose-dialog
        else
          notify "Please fill in all fields" -error
        end
    end
  end

Best Practices

  1. Message Organization: Use filters and search to help users find messages quickly
  2. Visual Feedback: Show unread indicators and use colors to highlight important messages
  3. Confirmation: Always confirm destructive actions like delete
  4. Auto-refresh: Keep the inbox updated without requiring manual refresh
  5. Responsive Design: Ensure your inbox works well on all screen sizes

Next Steps

Now that you’ve built a basic inbox, try adding:

Summary

You’ve learned how to:

The inbox system in Rhyme provides a powerful way to enable communication within your app. Use these patterns as a foundation for building more sophisticated messaging features!

Home
Get Startedwhat is rhyme? Your First App Sign Up

BlocksBlock Types [start] [init] [blocks]
ActionsDisplay Actions Input Actions Data Actions Flow Actions Understanding Actions
VariablesNaming Conventions Special Variables $variables
ValuesWorking with Text Text Number Switch Item Group Date Time Duration
ImagesBasics Displaying Images Image Sources
IconsBasics Icon Styling !icon select tool
ColorsColor Sets Sets Color Tool Dynamic Theme
FontsBasics Preview Fonts
TagsUnderstanding Tags Sounds
SoundsBeep Sounds Tap Sounds Event Sounds Slide Sounds

reference
Actions.10x1-image .12x1-image .16x9-image .1x1-image .1x2-image .1x3-image .1x4-image .1x6-image .1x8-image .2x1-image .2x3-image .3x1-image .3x2-image .4x1-image .4x3-image .4x5-image .5x4-image .6x1-image .6x9-image .8x1-image .a .account-signup .acknowledge .acknowledge-once .action-help .action-list .alt .announcement .app-frame .app-icon .app-iphone .app-laptop .app-navbar .app-tablet .aside .avatar .back .back-button .back-header .background-animated-gradient .background-color .background-gradient .background-image .background-video .banner-divider .bluesky .bottom-center .bottom-left .bottom-navbar .bottom-panel .bottom-right .brand-screen .btn .busy-button .button .button-bar .chat-incoming .chat-input .chat-outgoing .chat-typing .checkbox-field .chip .circle-button .circle-image .click .close-icon .color-input .color-palette .color-swatch .column .confetti .continue-button .copy-textbox .copyright .corner-banner .date-input .details .devfooter .dialog .dicebear-avatar .div .divider .divider-bar .edit-app .editor .enter .enter-date .enter-email .enter-family-name .enter-fullname .enter-given-name .enter-helptext .enter-number .enter-password .enter-phone .enter-text .enter-time .enterkey-effect .error-line .facebook .filler .fineprint .fixed-footer .font-sample .footer .footer-nav .full-panel .fullscreen-error .github .golden-image .goleft-effect .goto .goto-effect .gradient .grid .grid-cell .handwriting .header .help .hide .hide-in-progress .hover-over .hr .icon .icon-avatar .icon-button .icon-with-label .iframe .image .image-avatar .image-button .image-header .image-title .inbox-message .inbox-message-input .initials-avatar .input .instagram .left-panel .link .linkedin .list .list-item .live-search .lottie .megaicon .menu .menu-item .middle-center .middle-left .middle-right .mobile-app-view .navigation-bar .navto .number .option .overlay .paragraph .paragraph-text .password-field .password-panel .paste-background .pinpad-input .placeholder .popup .popup-screen .profile .progress-bar .progress-circle .progress-circle-with-value .qrcode .radio-field .rhappsody .rhyme-editor .rhyme-example .rhyme-live .rhyme-source .right-panel .row .run .screen .screen-background .search .select .select-field .set .shape-divider .show-in-progress .signature .signature-pad .sim-app .simulate .simulator .slider-input .spacer .span .spinner .splash-screen .stack .tagline .text .text-field .textarea .textbox-field .textbox-input .time-input .tint .tiptext .title .top-appbar .top-center .top-left .top-panel .top-right .turnstile .twitter .upload-csv .upload-file .upload-file-input .upload-image .upload-json .user-login .validate-email .value .video .video-banner .video-button .wait .when-load-complete .youtube .youtube-video +attachable +decorate +paste-image +paste-image +tint +when-close +when-load-complete account-ctx account-login account-logout account-signup action add add-days add-line add-row add-text add-weeks admin-login ai-auth ai-context ai-model ai-provider allow-dynamic-actions and app app-authorization app-colors app-context app-context-server app-data app-expires-on app-font app-golive-on app-host app-image app-mode app-name app-password app-private app-public app-sound appdev average background-image bluesky break browser-version build-app calculate capitalize character clear-acknowledgement clear-announcement clear-client clear-icons clear-image clear-images clear-inbox clear-profile close-menu color compile conditional confetti console-error console-info console-log console-var contains continue core-kv-get core-kv-put core-run corner-banner create-key create-table csv day-names days-between days-until decode-secret decrement decrypt default default-style delay delete delete-all-videos delete-app-data delete-app-image delete-appgroup delete-column delete-inbox-message delete-key delete-public-app-data delete-public-user-data delete-row delete-saved delete-user-data dir-action dir-actions dir-app dir-blocks dir-boot dir-build dir-clear dir-clear-inbox dir-compile dir-compiler dir-current dir-delay dir-delete-appgroup dir-delete-image dir-dev dir-edit dir-edit-block dir-files dir-help dir-hide dir-images dir-inbox dir-list-apps dir-list-groups dir-load dir-login dir-login-if-needed dir-logout dir-mock-date dir-new dir-new-appgroup dir-new-image dir-publish dir-regen-keys dir-secrets dir-send-inbox-message dir-set dir-sets dir-shell dir-show dir-source dir-source-default dir-status dir-users dir-who distance-between divide down-key dynamic-action dynamic-color-theme editor-login editor-onkey enable-shell-shortcut encrypt endconditional english ensure-email enter-date enter-email enter-family-name enter-fullname enter-given-name enter-helptext enter-key enter-number enter-password enter-phone enter-text enter-time equals error-line escape-key exit-module facebook fadein fadeout fake fake-date fake-table fake-time fill-column filter-group first-row font foreach forget fullscreen-error generate-app-key get-ip-location get-item-number get-location get-public-key get-recipe get-row github goto groq-ai-chat groq-models have hide host-call http-delete http-get http-post http-put icon if if-fail if-is-closed if-is-open if-success image increment init-all init-animation init-auth init-chat init-client init-compiler init-help init-images instagram is-appgroup-available is-date is-greater-than is-group is-item is-less-than is-number is-time is-valid-email is-valid-phone key last-row launch-module left-key length-of linkedin list-actions list-actionsets list-app-data list-app-images list-appgroups list-apps list-areas list-color-palettes list-colors list-compilers list-dynamic-actions list-fonts list-icons list-images list-inbox list-public-app-data list-public-user-data list-recipes list-saved list-secrets list-user-data list-videos load load-app load-app-data load-audio load-binary-file load-compiler load-json-file load-public-app-data load-public-user-data load-saved load-source load-text-file load-user-data logic loop lowercase manager-login max missing modulo month-names multiply my-approups new-app new-appgroup new-profile noop not not-equals on-incoming-chat-message on-notification open-browser open-browser-window open-menu openai-chat pause-audio person pick-random play-audio print print-error print-header profile protect-with-password proxy publish-bin publish-html publish-private random-between random-dice-roll random-digits random-row random-text random-uuid register-actionset reload remember remove-secret render-recipe repeat resend-send-email reset-client resize-image restore-profile resume return right-key round round-down round-up run save save-app-data save-app-image save-public-app-data save-public-user-data save-source save-user-data say schedule secret send-email send-notification send-to-inbox server-run set set-active-schedule set-ai-service set-animation set-announcement set-app-bin set-app-source set-app-title set-brand-color set-build-mode set-css-variable set-debug-ui set-default set-default-font set-dev-mode set-email-bcc set-email-body set-email-cc set-email-from set-email-service set-email-subject set-email-to set-groq-api-key set-http-body set-http-header set-http-timeout set-iconset set-image set-language set-message-body set-message-from set-message-subject set-mock-mode set-private-key set-public-key set-resend-api-key set-secret set-sound set-start-block set-target-ag set-target-aid set-video set-voice set-voice-language shield show slide-down slide-left slide-right slide-up slot sort-column sort-group sort-table source-block-list source-delete-block source-get-block source-join-blocks source-split-blocks source-update-block space-between-lines space-key spanish split-text stack stop-audio store-profile style su-account su-accounts su-platform subscribe subtract sync-time-to-server test test-owner-auth test-server timer-start timer-stop toggle-menu top-left twitter typed-getters-example unpack-row unshield unsubscribe up-key upload-app-image uppercase use use-modules user user-data user-login vardump varref varset vibrate wait waitfor when youtube
action setsunderstanding action sets acknowledgement actions AI announcements appgroup audio auth avatars background barcodes blog browser buttons calendar chat client clipboard color column compiler components config core CSS data datetime debug decorator directive divider editor editors effects email enter error events examples exec feedback fields file flow fonts footers form goto groq group headers help HTML HTTP icons if images inbox init input inputs interaction keys language layout lists localstorage location log logic logicfn loops math media menus messaging mock modifier modules navigation network notifications numbers openai overlays paragraph platform print profile progress publish random recipes resend resources rhyme row rows screens search secrets security selects server services shell shield sim social sounds source specialfx speech stacks styling system table test testing text upload users utilities utils validate validation variables video view voice
advanced/shell Variable Types Mock Values environment
Tools/shell Rhyme Editor /shell Playground

TutorialsYour App's Inbox

Resources
Rhappsody Platform Community Discord Server

© 2025 Rhappsody