Running a frontend on its built-in sample data
How the website and the dashboard each run with no API at all, what works there, what the Sample data notice says, what happens when a connected API stops answering, and how to switch to your API or remove the sample data.
For the Full Stack package
What it is
The website and the dashboard each carry the answers of a seeded Northstack API, exported from it, so each runs on its own with no back-end: every screen of the dashboard, and the website's contact form and licence checkout, work as they do against the API. It is what a single frontend package runs on out of the box, and a "Sample data" notice at the bottom of every page says so, so nobody mistakes it for a connected back-end.
Turning it on and off
There is no flag. One setting decides, NEXT_PUBLIC_API_BASE_URL, compiled in when the app is built:
# empty or missing: the built-in sample data, no API needed
NEXT_PUBLIC_API_BASE_URL=
# set: your API, with the /api suffix
NEXT_PUBLIC_API_BASE_URL=http://localhost:8000/api- Without Docker,
yarn installandyarn devin the app's folder with no.envfile run on the sample data. A.envcopied from.env.examplepoints at the API onhttp://localhost:8000/apiinstead. - With Docker, build the image with
--build-arg NEXT_PUBLIC_API_BASE_URL=for the sample data. Without that argument the image is built for the API onhttp://localhost:8000/api. - The Full Stack's
docker compose up --buildalways builds both frontends with the API's address. - After changing the value, restart
yarn dev, or runyarn buildagain, or build the image again.
The dashboard on sample data
| Area | On the sample data |
|---|---|
| Sign-in | Any password signs in. owner@, admin@, member@, billing@, platform@ and support@northstack.example each open that seeded account and its role, an account made on the sign-up page signs in as itself, and any other email opens the owner's. Empty or malformed fields are refused as the API refuses them. |
| Data | Forma Studio and Monogram in full, with their projects, boards, files, team, invitations, roles matrix, billing and invoices, API keys, activity and the assistant's past conversations, and the platform's organizations, users, staff, roles and settings. Every date is moved forward, so this week's activity is still this week's. |
| Changes | Real: creating a project, moving a card, inviting someone, editing the roles matrix, buying a plan through the test checkout or suspending an organization changes the data, and survives a reload, in that browser only. |
| Permissions | Checked as the API checks them, from each workspace's roles matrix, so every role sees exactly what it would see against the API. |
| Billing | As on an API without Stripe keys: an upgrade goes through the built-in test checkout, a downgrade is scheduled for the renewal and Keep takes it back. Invoices download as PDF. |
| None is sent. An invitation or password reset link is written to the browser's console instead, and works there. | |
| Live updates | None: the bell shows the activity already in the sample. |
| API keys | Created and revoked, with the secret shown once, but a key authenticates nothing, since there is no API. |
| AI assistant | Its past conversations and the seeded card of tasks show. A new question first asks for a provider key, then answers that the assistant needs the API; no model is called. |
Every answer is delayed a fraction of a second on purpose, so the loading states the dashboard ships with are seen.
The website on sample data
The home page and every content page never call the API, so they look the same either way. The two parts that do call it answer in the browser, and on the server for the first paint, from the sample data:
| Area | On the sample data |
|---|---|
| Licence checkout | Checked as the API checks it. Both card and PayPal go to the site's own Test checkout at /checkout/test: Pay marks the order paid and the receipt shows a licence key; Cancel payment cancels it. The amount is the licence's price, whatever the browser sends. |
| Contact form | Checked field by field as the API checks it, and answered with a success. Nothing is sent anywhere. |
| What visitors send | Orders and messages are kept in that browser only, so a receipt still shows its key after a reload. |
| Mail and limits | No receipt or message is mailed, and the API's per-address limits on the two forms do not apply. |
The Sample data notice
While the sample data answers, a "Sample data" notice sits at the bottom of every page, at the end of the page rather than over it, so scrolled to the end it covers nothing. Dismiss hides it until the next full page load.
| App | With no API set | With an API set that does not answer |
|---|---|---|
| Dashboard (every page, the sign-in page included) | "No API is connected, so this dashboard runs on built-in sample data and your changes stay in this browser. Any password signs in: owner@, admin@, member@, billing@, platform@ or support@northstack.example opens that role." | "The API at http://localhost:8000/api is not answering, so this dashboard is showing built-in sample data, not your workspace's. Changes made now stay in this browser. Start the API, then reload this page." |
| Website | "No API is connected (NEXT_PUBLIC_API_BASE_URL is empty), so the site runs on built-in sample data: the contact form and the license checkout answer in this browser and send nothing. Set NEXT_PUBLIC_API_BASE_URL in .env to use your API." | "The API at http://localhost:8000/api is not answering, so this site is showing built-in sample data. Orders and messages sent now stay in this browser. Start the API, then reload this page." |
The address in the second column is whatever the app was built with. While the dashboard runs on the sample data, its workspace footer also says "Sample data for demonstration."; on its own API it never does.
When a connected API stops answering
With NEXT_PUBLIC_API_BASE_URL set, the sample data also stands in when the API cannot be reached at all: not running, a timeout, or blocked because its CORS_ORIGIN does not list the app. An answer the API gave, even a 404 or a 500, is always shown as it is.
- After a failure the API is asked again at most every 30 seconds, and the app goes back to it as soon as it answers.
- The dashboard shows its notice whenever it stands in.
- The website stands in only in the browser: a page its server renders never shows sample data. Its notice shows in
yarn dev, and in a production build only when it was built withNEXT_PUBLIC_SAMPLE_DATA_NOTICE=always(in.envbeforeyarn build, or--build-arg NEXT_PUBLIC_SAMPLE_DATA_NOTICE=alwayswith Docker). - This covers an API that stopped, not an app with no API: the browser keeps trying the address and logs each refused request in its console. With no API at all, leave the address empty.
Switching to your API
Set NEXT_PUBLIC_API_BASE_URL to the API's address with the /api suffix, then restart yarn dev or build again. The API must list the app's address in its CORS_ORIGIN. What was changed on the sample data stays in that browser and is not sent to the API.
cp .env.example .env
yarn devStart over
Clear the site's data for the app's address in the browser's settings, or run one of these in the browser's console, and the samples come back as they shipped:
localStorage.removeItem("northstack_mock_db_v1"); location.reload();localStorage.removeItem("northstack_site_mock_db_v1"); location.reload();Removing it
Once an app runs on your own API for good, delete the sample data from its code, in the app's folder:
yarn remove:mock- It deletes
src/lib/mock/and the notice (src/components/SampleDataNotice/) with its messages, removes every block markedmock-apiin the code, in.env.example, in theDockerfileand in the app's own guides, and in the Full Stack the marked passages of the rootQUICKSTART.mdandREADME.md, and leavesremove:mockas a one-line note that the sample data is already removed. On the website it also drops the documentation lines tagged{mock}. Each file reads as it would had the sample data never been added. yarn remove:mock --dry-runlists the changes without making them, and a second run reports nothing left to do. It works before or afteryarn remove:demo.- The app then needs
NEXT_PUBLIC_API_BASE_URLset. Runyarn typecheckandyarn buildafterwards. - It deletes code and cannot be undone without version control, so commit first.
Exporting it again from the API
The sample data is the seeded API's own answers, so after you change the seed, export it again. In back-end, with the API seeded and running:
back-endyarn export:mockIt signs in as each seeded account, reads what the two apps show, and writes the dashboard's and the website's seed files beside it, in ../dashboard/src/lib/mock/db/seed/ and ../website/src/lib/mock/db/seed/. Nothing is written to the database. --api http://host:8000 reads another API. A browser holding an older copy discards it on its next load.
How it is built
Included with your purchase. Sign in to read, or open it in your download.
Where the sample data lives in each app, how a request reaches it, and keeping it in step with your API.