Features
Browse listings
View open and closed listings with filtering. Closed listings are capped at a configurable maximum via
MAX_BROWSE_LISTINGS.Common Application
Multi-step application flow covering contact, household, financial, community types, preferences, programs, and review.
Account management
Create an account, sign in, and access a dashboard showing all submitted applications and saved favorites.
Finder tool
Guided questionnaire that matches housing seekers to relevant listings based on their situation.
Get assistance
Connects applicants with local housing counselor services configured via
HOUSING_COUNSELOR_SERVICE_URL.FAQ
Frequently asked questions page, shown when the
SHOW_PUBLIC_LOTTERY feature flag is enabled.Page structure
All pages live undersites/public/src/pages/.
Top-level pages
Top-level pages
| File | Route | Description |
|---|---|---|
index.tsx | / | Homepage with featured listings |
listings.tsx | /listings | All open listings |
listings-closed.tsx | /listings-closed | Closed/waitlisted listings |
finder.tsx | /finder | Listing finder questionnaire |
get-assistance.tsx | /get-assistance | Housing counselor service |
faq.tsx | /faq | FAQ (feature-flagged) |
create-account.tsx | /create-account | New account registration |
sign-in.tsx | /sign-in | Sign-in page |
forgot-password.tsx | /forgot-password | Password reset request |
reset-password.tsx | /reset-password | Password reset confirmation |
verify.tsx | /verify | Email verification |
disclaimer.tsx | /disclaimer | Site disclaimer |
privacy.tsx | /privacy | Privacy policy |
additional-resources.tsx | /additional-resources | Additional housing resources |
create-advocate-account.tsx | /create-advocate-account | Advocate account registration |
Listing pages (/listing)
Listing pages (/listing)
| File | Route | Description |
|---|---|---|
listing/[id].tsx | /listing/[id] | Listing detail page |
listing/[id]/ | /listing/[id]/... | Nested listing subpages |
Application pages (/applications)
Application pages (/applications)
The Common Application is a multi-step flow. Each step is a separate page under
applications/:| Directory | Step |
|---|---|
applications/start/ | Eligibility screening and application entry |
applications/contact/ | Applicant contact information |
applications/household/ | Household members and details |
applications/financial/ | Income and financial information |
applications/community-types/ | Community type preferences |
applications/preferences/ | Local preference selections |
applications/programs/ | Program eligibility |
applications/review/ | Final review and submission |
applications/view.tsx | View a submitted application |
Account pages (/account)
Account pages (/account)
| File | Route | Description |
|---|---|---|
account/dashboard.tsx | /account/dashboard | Overview of submitted applications |
account/edit.tsx | /account/edit | Edit account profile |
account/application/[id]/ | /account/application/[id] | View a specific submitted application |
account/applications/ | /account/applications | List of all submitted applications |
account/favorites/ | /account/favorites | Saved/favorited listings |
Running locally
Configure environment variables
Copy the template and set values for your local environment:Edit
sites/public/.env as needed. See the environment variables section below for details on each variable.Start the backend and public app
From the monorepo root, this starts the backend on port 3100 and the public portal on port 3000:Alternatively, start only the public portal from within
sites/public:Open the app
Navigate to http://localhost:3000 in your browser.
The backend must be running on port 3100 before starting the public portal. The app will fail to load listings if the API is unreachable.
Environment variables
Copy.env.template to .env inside sites/public/. The following variables control the app’s behavior:
API and backend
API and backend
| Variable | Default | Description |
|---|---|---|
BACKEND_API_BASE | http://127.0.0.1:3100 | Base URL for the backend API |
BACKEND_API_BASE_NEW | http://127.0.0.1:3100 | Alternate base URL (used for new API paths) |
BACKEND_PROXY_BASE | (empty) | If set, routes API calls through this proxy instead |
LISTINGS_QUERY | /listings | Path appended to backend base to query listings |
API_PASS_KEY | some-key-here | Shared passkey; must match the backend’s configured value |
Application behavior
Application behavior
| Variable | Default | Description |
|---|---|---|
NEXTJS_PORT | 3000 | Port the Next.js app listens on |
JURISDICTION_NAME | Bloomington | Display name for the jurisdiction |
LANGUAGES | en,es,zh,vi,tl,bn,ar,ko,hy,fa | Comma-separated list of supported locales |
IDLE_TIMEOUT | 5 | Minutes of inactivity before session timeout |
HOUSING_COUNSELOR_SERVICE_URL | /get-assistance | URL for housing counselor service page |
MAX_BROWSE_LISTINGS | 10 | Maximum number of closed listings shown on the closed listings page |
CACHE_REVALIDATE | 30 | Seconds to cache listing detail pages server-side (ISR revalidation interval) |
MAINTENANCE_WINDOW | (empty) | Date range (YYYY-MM-DD HH:mm Z,YYYY-MM-DD HH:mm Z) for maintenance mode banner |
SITE_MESSAGE_WINDOW | (empty) | Date range for displaying a site-wide message banner |
Third-party integrations
Third-party integrations
| Variable | Default | Description |
|---|---|---|
MAPBOX_TOKEN | (empty) | Mapbox API token for listing map views |
CLOUDINARY_CLOUD_NAME | exygy | Cloudinary cloud name for listing images |
GA_KEY | G-2WQMFT5BES | Google Analytics measurement ID |
GTM_KEY | GTM-KF22FJP | Google Tag Manager container ID |
NEW_RELIC_APP_NAME | Bloom Public | New Relic application name |
NEW_RELIC_LICENSE_KEY | (empty) | New Relic license key |
SENTRY_ORG | (empty) | Sentry organization slug; when set, enables Sentry error tracking |
RECAPTCHA_KEY | (empty) | Google reCAPTCHA site key |
AXE_DEVELOPER_HUB_API_KEY | (empty) | Axe DevHub API key for automated accessibility reporting |
Feature flags
Feature flags
| Variable | Default | Description |
|---|---|---|
SHOW_PUBLIC_LOTTERY | TRUE | Enables lottery-related UI and the FAQ page |
SHOW_MANDATED_ACCOUNTS | FALSE | Requires applicants to create an account before applying |
SHOW_PWDLESS | FALSE | Enables passwordless (magic link) authentication |
SHOW_NEW_SEEDS_DESIGNS | FALSE | Enables updated UI using the latest ui-seeds design tokens |
ALLOW_SEO_INDEXING | FALSE | Set to TRUE in production only; enables search engine indexing |
RUN_ACCESSIBILITY_E2E_TESTS | FALSE | Enables accessibility checks in the Cypress E2E suite |
Testing
The public portal has two test suites.- Cypress (E2E)
- Jest (unit/integration)
Run the full end-to-end test suite against a running instance of the app:Run from within
sites/public/ with the app already running on port 3000.Set
RUN_ACCESSIBILITY_E2E_TESTS=TRUE in .env to also run axe-based accessibility checks during the Cypress suite.