This Next.js application can be run natively (or locally)
Running locally is the default, but it can be useful to run the built Docker images in order to more closely simulate our deployed environment, troubleshoot production issues, and to connect directly with the local API application for development.
Running a local server requires the version of Node specified in the .nvmrc file to be installed.
This project supports the use of NVM for node version management, so it is suggested you intall and use NVM. More infomrmation can be found in this guide.
- For Mac - Run
npm install && npm run localto install and start the application. - For Windows - First follow this guide for installing Node Version Manager (How to Install NVM on Windows). Then in Windows PowerShell in the \simpler-grants-gov\frontend directory, run
npm installto install the application. Runnpx next devafterwards to start the application.
Optionally, disable telemetry data collection
npx next telemetry disableCreate a local environment file in the frontend directory to hold your frontend application overrides. This allows you to make specializations to your local setup without the danger of committing any secrets to GitHub.
On Mac, run touch .env.local
On Windows, run ni .env.local in PowerShell.
For more information about environments, take a look at environments.md.
Running authentication locally requires running the API and sharing the correct JWT keys.
- Ensure you've completed the API setup, including creating the
override.envfile - Copy the
API_JWT_PUBLIC_KEYvalue from/api/override.envfile to your/frontend/.env.localfile which creates the necessary keys - Restart the API (if necessary reseed the database, then
make start) - Restart the frontend (on Mac,
npm run local, and on Windows,npx run dev) for development
The Next.js frontend application is exported for production using next build. To recreate this locally, outside of the container, run the following:
npm run build- Builds the production Next.js bundlenpm start- Runs the Next.js server, after building the production bundle
Alternatively, you can run the application in a Docker container.
Note: If you are running docker locally for the first time, you need to run the API locally through Docker as well, in order to create the required api_grants_backend network.
From the /frontend directory:
- Run the local development server
make dev
- Navigate to localhost:3000 to view the application
- If installing new packages locally with npm and using
make devwith docker to run locally, you may need to runmake buildfirst to bring the new packages into the container
The make dev command runs the docker-compose.yml which runs the dev target in the Dockerfile. To run a production version in docker, run docker compose up -d -f docker-compose-realease.yml which targest the release stage in the docker build. This runs the production version, while still creating a network connection to the local API.
To test the release target locally, run:
make release-build OPTS="--tag [IMAGE_NAME]"ordocker buildx build --target release --tag [IMAGE_NAME]for a faster build on OSX
to build a local image. To view the site at localhost:3000, run: docker run -e "HOSTNAME=0.0.0.0" -p 3000:3000 [IMAGE_NAME].
Jest is used as the test runner and React Testing Library provides React testing utilities.
Tests are manged as .test.ts (or .tsx) files in the the tests/ directory.
To run tests:
npm test- Runs all tests and outputs test coverage reportnpm run test-watch- Runs tests in watch mode. Tests will re-run when files are changed, and an interactive prompt will allow you to run specific tests or update snapshots.
A subset of tests can be run by passing a pattern to the script. For example, to only run tests in tests/pages/:
npm run test-watch -- pagesA single test can be run by appending .only to the test. For example:
describe('MyComponent', () => {
it.only('should render correctly', () => {
// ... test logic
});Playwright is a framework for web testing and its test runner is called Playwright Test, which can be used to run E2E or integration tests across chromium, firefox, and webkit browsers.
E2E test filenames end with .spec.ts and are found in the tests/e2e directory.
To run E2E tests via CLI:
cd ../api && make remake-backend start(prerequisite to start the API)npx playwright install --with-deps— Downloads playwright browsers required to run testsnpm run test:e2e— Runs all E2E tests using the playwright config found attests/playwright.config.tsnpm run test:e2e:ui— Run specific or all E2E tests using Playwright's UI mode, which is useful for debugging full traces of each test
To run E2E tests using VS Code:
- Download the VS Code extension described in these Playwright docs
- Follow the instructions Playwright provides
Playwright E2E tests run "local-to-local", requiring both the frontend and the API to be running for the tests to pass - and for the database to be seeded with data.
In CI, the "Frontend Checks" workflow (.github/workflows/ci-frontend-e2e.yml) runs Playwright tests, and will include a summary when complete, with an "Artifacts" section where there is an attached "playwright-report". Playwright docs describe how to view the HTML Report in more detail.
- TypeScript is used for type checking.
- ESLint is used for linting. This helps catch common mistakes and encourage best practices.
- Prettier is used for code formatting. This reduces the need for manual formatting or nitpicking and enforces a consistent style.PRs in Github Actions, other than e2e tests
It's recommended that developers configure their code editor to auto run these tools on file save. Most code editors have plugins for these tools or provide native support.
VSCode instructions
-
Add the following to a
.vscode/settings.jsonWorkspace Settings file:{ "editor.codeActionsOnSave": { "source.fixAll.eslint": true }, "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode", "eslint.workingDirectories": ["./frontend"], "typescript.validate.enable": true }For these tools to auto run, the settings must be located in the root of your current VSCode workspace. For example, if you open the
frontend/directory in VSCode, the settings should be located atfrontend/.vscode/settings.json. If you then open then root repository directory in VSCode as your workspace, these tools will not auto run. (Note that adding the settings to the root repository directory may affect other parts of a monorepo.)You can alternatively add the settings to your User Settings, however they will apply globally to any workspace you open. See User and Workspace Settings for more guidance.
npm run ts:check- Type checks all filesnpm run lint- Lints all files and reports any errorsnpm run lint-fix- Lints all files and fixes any auto-fixable errorsnpm run format: Formats all files based on prettier rulesnpm run format-check: Check files for prettier formatting violations without fixing themnpm run all-checks: Runs linting, typescript check, unit testing, and creates a build - simulating locally tests that are run on PRs in Github Actions, other than e2e tests
Storybook is a frontend workshop for developing and documenting pages and components in isolation. It allows you to render the same React components and files in the src/ directory in a browser, without the need for a server or database. This allows you to develop and manually test components without having to run the entire Next.js application.
See the Storybook Next.js documentation for more information about using Storybook with Next.js
Similar to the Next.js application, Storybook can be ran natively or in a Docker container.
From the frontend/ directory:
npm run storybook- Navigate to localhost:6006 to view
npm run storybook-build- Exports a static site tostorybook-static/
Alternatively, you can run Storybook in a Docker container.
From the frontend/ directory:
make storybook- Navigate to localhost:6006 to view
- See the debug config:
./.vscode/launch.json- There are several debug config targets defined there depending on if you want to debug just client components (client-side), just server components (server-side), or both (with the Full Stack option). You can also debug the built server (launched from
npm startinstead ofnpm run dev).
- There are several debug config targets defined there depending on if you want to debug just client components (client-side), just server components (server-side), or both (with the Full Stack option). You can also debug the built server (launched from
- Run one of these launch targets from the VSCode debug menu
- Place breakpoints in VSCode
- Visit the relevant routes in the browser and confirm you can hit these breakpoints
Note that debugging the server-side or full-stack here doesn't debug the API. See the API readme for more information
The following features require additional local setup to use.
The /search and opportunity pages rely on the application API. The API endpoint and authentication token are defined in .env.development and can be overwritten in an .env.local file.
The API_URL environment variable can be set to connect to prod (https://api.simpler.grants.gov) or lower environment URLs to quickly develop using production or development data. To successfully connect to a deployed API, the API_AUTH_TOKEN variable must be set correctly for the environment.
To start a local development version of the API, run make remake-backend in the /api folder.
See documentation/api/development.md for more details.
The documentation/api/authentication.md details the login flow from the frontend → API → login.gov → API → frontend.
The /api/auth/callback route handler receives a JSON web token as query parameter, uses the API_JWT_PUBLIC_KEY env variable to verify that it was created by the API, sets a cookie with the token, then later uses that token to verify the user identity in /api/auth/session and other routes.
When clicking "Sign in" or other buttons that simulate the login flow locally, shoule be redirected to the mock Oauth2 server at http://localhost:5001. Enter any text string in the screen provided to continue the login flow.
Some functionality will not work locally without supplying the application environment variables containing secrets.
- New Relic
NEW_RELIC_APP_NAMENEW_RELIC_LICENSE_KEY
- Email subscription form (Sendy)
SENDY_API_KEYSENDY_API_URLSENDY_LIST_ID
If you need to access this functionality locally, contact an engineer on the team to get access to the necessary secrets.
- Internationalization
- Feature Flags
- Refer to the architecture decision records for more context on technical decisions.