UNPKG

@trycourier/courier-ui-inbox

Version:

Inbox components for the Courier web UI

381 lines (276 loc) 10.7 kB
<img width="1040" alt="courier-ui-inbox" src="https://github.com/user-attachments/assets/6227249b-d008-4719-bddc-874f34432376" /> ## 1. Install ```sh npm install @trycourier/courier-ui-inbox ``` > **Using React?** We suggest you use [@trycourier/courier-react](../courier-react/README.md) package instead. ## 2. Authenticate To use the SDK, you need to generate a JWT (JSON Web Token) for your user. **This JWT should always be generated by your backend server, never in client-side code.** **How it works:** 1. **Your frontend calls your backend:** - When your app needs to authenticate a user, your frontend should make a request to your own backend (e.g., `/api/generate-courier-jwt`). 2. **Your backend calls Courier to issue a JWT:** - In your backend endpoint, use your [Courier API Key](https://app.courier.com/settings/api-keys) to call the [Courier JWT Token Endpoint](https://www.courier.com/docs/reference/auth/issue-token) and generate a JWT for the user. - Your backend then returns the JWT to your frontend. To quickly test JWT generation (for development only), you can use the following cURL command to call Courier's API directly. **Do not use this in production or from client-side code.** ```sh curl --request POST \ --url https://api.courier.com/auth/issue-token \ --header 'Accept: application/json' \ --header 'Authorization: Bearer $YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --data \ '{ "scope": "user_id:$YOUR_USER_ID write:user-tokens inbox:read:messages inbox:write:events read:preferences write:preferences read:brands", "expires_in": "$YOUR_NUMBER days" }' ``` ## 3. Add Inbox Component ### `courier-inbox` <img width="688" alt="Screenshot 2025-06-25 at 2 32 30 PM" src="https://github.com/user-attachments/assets/93246c34-3c5a-475e-8e83-7df6acf9bdf3" /> ```html <body> <courier-inbox id="inbox"></courier-inbox> <script type="module"> import { Courier } from '@trycourier/courier-ui-inbox'; // Generate a JWT for your user (do this on your backend server) const jwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'; // Replace with actual JWT // Authenticate the user with the inbox Courier.shared.signIn({ userId: $YOUR_USER_ID, jwt: jwt }); </script> </body> ``` ### `courier-inbox-popup-menu` <img width="602" alt="Screenshot 2025-06-25 at 2 33 17 PM" src="https://github.com/user-attachments/assets/c3b7f4cc-26c1-4be6-9ed5-a3fc3c0b335b" /> ```html <body> <div style="padding: 24px;"> <courier-inbox-popup-menu id="inbox"></courier-inbox-popup-menu> </div> <script type="module"> import { Courier } from '@trycourier/courier-ui-inbox'; // Generate a JWT for your user (do this on your backend server) const jwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'; // Replace with actual JWT // Authenticate the user with the inbox Courier.shared.signIn({ userId: $YOUR_USER_ID, jwt: jwt }); </script> </body> ``` ## Handle Clicks and Presses ```html <body> <courier-inbox id="inbox"></courier-inbox> <!-- or use courier-inbox-popup-menu --> <script type="module"> import { Courier } from '@trycourier/courier-ui-inbox'; // Generate a JWT for your user (do this on your backend server) const jwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'; // Replace with actual JWT // Authenticate the user with the inbox Courier.shared.signIn({ userId: $YOUR_USER_ID, jwt: jwt }); // Reference the element const inbox = document.getElementById('inbox'); // Handle message clicks inbox.onMessageClick(({ message, index }) => { alert("Message clicked at index " + index + ":\n" + JSON.stringify(message, null, 2)); }); // Handle message action clicks (These are buttons on individial messages) inbox.onMessageActionClick(({ message, action, index }) => { alert( "Message action clicked at index " + index + ":\n" + "Action: " + JSON.stringify(action, null, 2) + "\n" + "Message: " + JSON.stringify(message, null, 2) ); }); // Handle message long presses. **Only works on devices that support javascript's touch events. This will not work with a mouse cursor.** inbox.onMessageLongPress(({ message, index }) => { alert("Message long pressed at index " + index + ":\n" + JSON.stringify(message, null, 2)); }); </script> </body> ``` ## Styles and Theming ### Light & Dark Themes The fastest way to style the Inbox to match your app. This example shows unread indicator styling, but you can customize fonts, icons, text, and more. > **🎨 Theme Reference:** [All available theme values](./docs/theme.md) <img width="688" alt="Screenshot 2025-06-25 at 2 36 20 PM" src="https://github.com/user-attachments/assets/982164fe-fe0d-4e66-82d1-b5a6571f1aa4" /> ```html <body> <courier-inbox id="inbox"></courier-inbox> <!-- or use courier-inbox-popup-menu --> <script type="module"> ... // Reference the element const inbox = document.getElementById('inbox'); const theme = { inbox: { header: { filters: { unreadIndicator: { backgroundColor: "#8B5CF6" } } }, list: { item: { unreadIndicatorColor: "#8B5CF6" } } } } // Set the theme inbox.setLightTheme(theme); inbox.setDarkTheme(theme); // Set the mode // This will force light, dark or system theme mode inbox.setMode('light'); </script> </body> ``` ### Popup Alignment, Positioning, and Dimensions ```html <body> <div style="display: flex; justify-content: center; align-items: center; padding: 100px;"> <!-- Available alignments: 'top-right' | 'top-left' | 'top-center' | 'bottom-right' | 'bottom-left' | 'bottom-center' | 'center-right' | 'center-left' | 'center-center' --> <courier-inbox-popup-menu popup-alignment="top-right" top="44px" right="44px" popup-width="340px" popup-height="400px"> </courier-inbox-popup-menu> </div> ... </body> ``` ### Custom height `courier-inbox` > **Important:** The default `courier-inbox` height is auto. It will set it's height based on it's children. ```html <body> <courier-inbox height="50vh"></courier-inbox> ... </body> ``` ## Custom Elements Customize the inbox UI with any element you want. ### List Items <img width="688" alt="Screenshot 2025-06-25 at 2 37 29 PM" src="https://github.com/user-attachments/assets/53da26d1-ed9a-461d-ad92-2e74ee3e91bf" /> ```html <body> <courier-inbox id="inbox"></courier-inbox> <!-- or use courier-inbox-popup-menu --> <script type="module"> ... // Reference the courier-inbox element const inbox = document.getElementById('inbox'); // Set a custom list item inbox.setListItem(({ message, index }) => { const pre = document.createElement('pre'); pre.style.padding = '24px'; pre.style.borderBottom = '1px solid #e0e0e0'; pre.style.margin = '0'; pre.textContent = JSON.stringify(({ message, index }), null, 2); return pre; }); </script> </body> ``` ### Header <img width="688" alt="Screenshot 2025-06-25 at 2 38 45 PM" src="https://github.com/user-attachments/assets/d393f77d-695e-4fed-a60a-7f7b59909772" /> ```html <body> <courier-inbox id="inbox"></courier-inbox> <!-- or use courier-inbox-popup-menu --> <script type="module"> ... // Reference the courier-inbox element const inbox = document.getElementById('inbox'); // Remove the header inbox.removeHeader(); // Set a custom header inbox.setHeader(({ feedType, unreadCount, messageCount }) => { const headerDiv = document.createElement('div'); headerDiv.style.background = 'red'; headerDiv.style.fontSize = '24px'; headerDiv.style.padding = '24px'; headerDiv.style.width = '100%'; headerDiv.textContent = feedType; return headerDiv; }); // Change the feed type // "inbox" and "archive" are available inbox.setFeedType('archive'); </script> </body> ``` ### Popup Menu Button <img width="688" alt="Screenshot 2025-06-25 at 2 39 49 PM" src="https://github.com/user-attachments/assets/5eeb32ae-13ff-4622-b6ea-b302f04509f3" /> ```html <body> <div style="display: flex; justify-content: center; align-items: center; padding: 100px;"> <courier-inbox-popup-menu id="inbox"></courier-inbox-popup-menu> </div> <script type="module"> ... // Reference the courier-inbox element const inbox = document.getElementById('inbox'); // Set a custom menu button inbox.setMenuButton(({ unreadCount }) => { const button = document.createElement('button'); button.textContent = `Open the Inbox Popup. Unread message count: ${unreadCount}`; return button; }); </script> </body> ``` ### Loading, Empty, Error & Pagination ```html <body> <courier-inbox id="inbox"></courier-inbox> <!-- or use courier-inbox-popup-menu --> <script type="module"> ... // Reference the courier-inbox element const inbox = document.getElementById('inbox'); // Set a custom loading state inbox.setLoadingState(props => { const loading = document.createElement('div'); loading.style.padding = '24px'; loading.style.background = 'red'; loading.textContent = 'Custom Loading State'; return loading; }); // Set a custom empty state inbox.setEmptyState(props => { const empty = document.createElement('div'); empty.style.padding = '24px'; empty.style.background = 'green'; empty.textContent = 'Custom Empty State'; return empty; }); // Set a custom error state inbox.setErrorState(props => { const error = document.createElement('div'); error.style.padding = '24px'; error.style.background = 'blue'; error.textContent = 'Custom Error State'; return error; }); // Set a custom pagination state inbox.setPaginationItem(props => { const pagination = document.createElement('div'); pagination.style.padding = '24px'; pagination.style.background = 'yellow'; pagination.textContent = 'Custom Pagination Item'; return pagination; }); </script> </body> ``` > **Using React?** We suggest you use [@trycourier/courier-react](../courier-react/README.md) package instead. # **Share feedback with Courier** We want to make this the best SDK for managing notifications! Have an idea or feedback about our SDKs? Let us know! [Courier Web Issues](https://github.com/trycourier/courier-web/issues)