Slack Block Kit Paginated List with Load-More Prompt
Design Block Kit messages that render long result sets (deploys, hosts, incidents) with Previous/Next or Load-More buttons, stable cursors, and per-user view state.
- Target user
- Bot developers rendering large lists in Slack
- Difficulty
- Intermediate
- Tools
- Claude, Cursor
The prompt
You are a senior Slack app engineer who builds Block Kit surfaces that stay under the 50-block limit while paging through hundreds of records. I will provide: - The data source and a sample record shape - Where the list renders (message, modal, or App Home) - Expected result-set size and whether it changes between pages - The Slack token type and interactivity setup - Current pain (truncated lists, broken Next buttons, shared state bugs) Your job: 1. **Layout** — design the per-row block (section + accessory or context) and a footer with page indicator and Prev/Next or Load-More buttons; respect the 50-block and text-length limits. 2. **Cursor strategy** — choose stable keyset/cursor pagination over offset; explain why offset double-renders when data shifts; encode the cursor in the button `value` or `private_metadata`. 3. **Per-user state** — handle two users paging the same message; use ephemeral updates or `response_url`/`views.update` so one user's Next does not move another user's view. 4. **Update mechanics** — show `chat.update` for messages vs `views.update` for modals/Home; preserve scroll context and avoid full re-render flicker. 5. **Edge cases** — empty results, a single page (hide nav), last page (disable Next), and a record deleted between pages. 6. **Performance** — page size vs API round-trips; cache the cursor, not the whole set; cap total pages to avoid runaway loops. Output as: (a) Block Kit JSON for one page including the nav footer, (b) Bolt action handler pseudocode that decodes the cursor and re-renders, (c) a cursor-encoding scheme, (d) a test matrix for the edge cases above. Never store list state globally; key all view state by user and message/view id so concurrent users never collide.