Announcements
Super admin announcements: the scrolling bar and popup in Super People, notifications for important ones, and how superlabs.co shows them on its own site.
A super admin can put up a short announcement from Announcements in the Super People sidebar. It shows as a scrolling bar across the top of the app, as a popup, or both. It can also be offered to the public superlabs.co website.
- Route reference: Announcements API
- Base URLs:
http://localhost:3101local,https://api-peoples.superlabs.coproduction
What an announcement has
| Field | Notes |
|---|---|
message | Up to 200 characters. Emoji are allowed and an emoji counts as one character. Plain text, never HTML. |
linkUrl / linkLabel | An optional "Know more" link. It must be a full http(s):// address. The label defaults to Know more. |
display | bar, popup or both. |
startsAt / endsAt | The window it is live in. An empty start means now. An empty endsAt ("date till") runs until a super admin ends it. |
important | Also sends it as a notification. See Important announcements. |
Who sees it
Three switches, which can be combined. At least one is required.
| Option in the form | Field | Who |
|---|---|---|
| Website | onWebsite | Visitors to superlabs.co. This needs the website to show it; see On superlabs.co. |
| Organization | toEveryone | Everyone signed in to Super People. |
| Individuals | recipientIds | Only the people picked. |
Website alone does not show anything inside Super People. Organization and Individuals do not put anything on the website.
Website is hidden in the form for now. It is commented out in
apps/web/components/announcements/announcement-form-dialog.tsxuntil superlabs.co shows announcements, because ticking it changes nothing anyone can see yet. The API and the public route still support it. To bring it back, uncomment theCheckfor Website in that file.
Closing it
The bar and the popup each have a close button. A closed announcement stays closed while the person moves between pages, after a reload and in other tabs. This is remembered in the browser for each viewer, and separately for the bar and the popup.
Closing is keyed on id and updatedAt. When a super admin edits an
announcement, people who closed it see the new wording.
Important announcements
With Important ticked, the announcement also goes out as a notification
of kind announcement: the bell, an alert on any open page, and a push. It
goes to everyone it is for, apart from the super admin who wrote it.
- It is sent once, when it goes live. A scheduled one is sent when it starts. The API has no scheduler, so the first signed-in request after the start sends it. While anyone has the app open, that is within about a minute.
- Editing it later does not send it again.
- Opening the notification shows the announcement in the popup again, even if it was closed.
- Website visitors are never notified.
On superlabs.co
Ticking Website only makes the announcement available from a public route. The website shows it once it has the code below, in the same way the Office Updates page reads its posts.
1. Fetch from the website's server
GET https://api-peoples.superlabs.co/api/v1/public/announcements- No session and no key are needed.
- Call it from the website's server (server-side rendering, an API route or a server component), not from the visitor's browser. The API only accepts browser requests from Super People's own origins (CORS), so a browser call from superlabs.co is blocked.
- Responses carry
Cache-Control: public, max-age=60. An announcement that is ended or deleted can stay visible for up to a minute. - Treat a failed request as "no announcements". The bar is optional, so the page should never break because of it.
2. What comes back
An array of live announcements, newest first. It is empty when there are none.
[
{
"id": "a0f58db6-1c6c-45ac-94c1-6101ec42afc8",
"message": "🎉 The SuperLabs office will be closed on Friday for Diwali.",
"linkUrl": "https://superlabs.co/news/diwali",
"linkLabel": "Know more",
"display": "both",
"endsAt": "2026-10-24T18:30:00.000Z",
"updatedAt": "2026-10-06T05:32:25.284Z"
}
]Only announcements with Website ticked and inside their dates are returned. Who wrote them and who else sees them are never included.
3. Show it
- Bar: a strip across the top of every page with the
message, a button readinglinkLabelthat openslinkUrlin a new tab (rel="noopener noreferrer"), and a close (×) button. The app's bar scrolls, but a still bar is fine too. - Popup: for
displayofpopuporboth, a dialog with the same message and link may be shown. Showing the bar only is also fine. - Render
messageas text, never as HTML.
4. Remember the close
Once a visitor closes it, it must not come back on the next page. Store the
close in localStorage, keyed on both id and updatedAt, and skip those
announcements when rendering:
const key = (a) => `announcement-closed:${a.id}:${a.updatedAt}`
function isClosed(a) {
try {
return localStorage.getItem(key(a)) === "1"
} catch {
return false
}
}
function close(a) {
try {
localStorage.setItem(key(a), "1")
} catch {
// Storage blocked: it closes for this page only.
}
}The server cannot see localStorage, so do this filtering in the browser
after the page loads. Otherwise a closed bar flashes back on every page
before it disappears.
Checklist
- The API with the Announcements module is deployed to production. The
tables are in
apps/api/src/db/schema.sql. - A super admin creates an announcement with Website ticked and no start date.
- Within a minute,
GET /api/v1/public/announcementson production returns it. - The website shows the bar, the link opens in a new tab, and once closed it stays closed across pages.