Frontend
Introduction
Integrates’ frontend is a client-side rendered web application written in TypeScript and built with React.
Browser support
Supported browsers are listed in the Browser compatibility article.
Thanks to TypeScript, we can use newer ECMAScript language features, as it takes care of downleveling as needed when transpiling, but as for runtime features, it is important to ensure compatibility.
Helpful resources:
Principles
- Functional: The view should be a function of state and props. The codebase only uses functional components, avoids direct mutations and favors a declarative style.
- The state should not exist: Keep the state to a minimum.
- There’s a component for that: If there isn’t, feel free to create it.
- No need to reinvent the wheel: Sometimes, third-party packages have already figured it out.
Getting started
To observe changes as you edit the code, run the following command:
Moreover, the application and the local program are compiled using Vite, which facilitates React-refresh for real-time observation of changes.
Linting
The frontend uses ESLint, Prettier and Stylelint to enforce compliance with a defined coding style.
To view and auto-fix linting issues globally, you can run:
This linting process might take too long. Its default argument is all
, but
you can choose local
or commit
arguments as alternatives.
To run only for committed changes in the last HEAD, you can run:
To run only for local (non committed) changes above HEAD, you can run:
Testing
The frontend uses Jest as a test runner, MSW to mock API responses and the utilities provided by React Testing Library to test the UI behavior from a user perspective.
To execute the test cases on your computer, you can run:
To execute test cases individually, you can pass the path of the test as an argument to this command:
Core
State Management
- Transferred state: This makes up the majority of the frontend state. Data loaded from the backend is managed by the Apollo Client.
- Forms: Their ephemeral state is managed by Formik.
- Local state: useState and Context where needed.
- Additional state management: Zustand for simpler, more predictable state management in certain parts of the application.
API Client
The frontend uses the Apollo Client to interact with the backend.
You can use the useQuery
hook to load data
and the useMutation
hook to trigger create, update or delete operations.
Refer to Apollo’s documentation for more details.
Forms
The frontend uses Formik to power its forms, fields and validations.
You can use the <Formik>
component,
with inputs from src/components/Input
to compose forms,
and Yup to declare a validation schema to be checked on submit.
Refer to Formik and Yup’s documentation for more details.
Tables
The frontend uses TanStack Table to power its data tables, fitting them with features such as sorting, pagination, column toggling, row expansion, exports and more.
You can use the <Table>
component,
from src/components/Table
to build a table from a dataset and columns.
Refer to TanStack Table’s documentation for more details.
Tours
The frontend uses a custom hook to manage the status of tours.
You can use the useTour
hook, from src/hooks/use-tour
to get and set the current status of each Tour.
For example:
Authorization
Integrates uses Attribute-based access control to manage its authorization model, and the frontend uses some utilities from CASL to implement it.
You can do conditional rendering based on what the user is allowed to access:
You can also use it outside JSX
Feature preview
In a constantly evolving product, it may be useful to conduct A/B testing.
This strategy allows trying new ideas with a small subset of the users, analyzing reception, iterating and improving before releasing them to everyone.
You can do conditional rendering based on user preference:
Routing
The frontend uses React Router to declare routes and manage navigation between them.
You can use the <Route>
and <Switch>
components to declare routes,
the useParams
hook to get the URL parameters,
the <Link>
component for declarative navigation,
and the useHistory
hook for imperative navigation.
Refer to React Router’s documentation for more details.
Styling
The frontend uses styled-components and Tachyons to create and compose UI styles.
You can declare styled components with the styled
tag,
reference tachyons classes,
and also add custom CSS as needed.
Refer to styled-components and Tachyons’ documentation for more details.
Internationalization
The frontend uses i18next to manage translations.
While we currently support only English, more languages may be added later on, making it a good idea to avoid hardcoding texts and having them instead as translations.
You can declare texts in the respective file for the language,
at src/utils/translations
,
and then, use the useTranslation
hook to access them in the component.
Refer to i18next’s documentation for more details.
Dependencies
The frontend uses npm as its package manager.
When adding or updating dependencies, keep this requirement in mind. Always make sure to pin the dependency to an exact version, as semantic versioning is often unreliable and may cause regressions due to unexpected incompatibilities.
Refer to https://github.com/fluidattacks/makes#makenodejslock if you need to generate a lock file without having Node.js installed on your computer.
Logging
console.log
usage is not allowed
per https://eslint.org/docs/latest/rules/no-console,
though it can still be used locally for debugging.
You can use src/utils/logger.ts
,
which sends errors and warnings to Bugsnag,
the bug-tracking platform we currently use.
To access Bugsnag, sign in to your Okta account. If you can’t find the app, feel free to request access via help@fluidattacks.com
Design
Visual consistency is key to providing users with a good experience. This motivation led to the creation of the components library, a collection of UI components that can be easily used by developers and continuously refined by designers.
You can access it on:
- Production: design.fluidattacks.com
- Developer branch:
integrates.front.development.fluidattacks.com/branch-name/storybook/index.html
- Locally:
localhost:6006
, after runningm . /integrates/front storybook
Most of these components are implementations of the design guidelines defined by the Customer Experience team at Fluid Attacks.
Resources
Our platform utilizes various media assets, including images, GIFs, and other media to enhance user experience. These resources are hosted and managed through Cloudinary. Our developers can access and manage these assets via our Cloudinary media explorer here.
API type safety
The API features a fully typed schema. This frontend can leverage it by generating TypeScript types, ensuring accurate interactions with the backend.
To regenerate these types, execute m . /integrates/front/types
.
Tooling
Helpful tools that enhance development experience when working on the frontend:
- vscode gitlens
- react developer tools
- apollo client devtools
- vscode eslint
- vscode jest
- vscode prettier
- semver calculator
Troubleshooting
Helpful tips and tricks that have proven to be useful when diagnosing issues on the frontend:
- How do I do X?: Refer to the documentation of the core packages mentioned above. If that doesn’t solve it, feel free to reach out for help on the engineering chat.
- Why is X not working?: Look for error traces on the browser console or use breakpoints to inspect the code and variable values as it runs.
- Is the backend returning an error?: Use the network tab to view more details about the request and its response.
- Can’t find an element on a test?: Try increasing the print limit to view more details and suggestions or try a snippet on testing playground.
Frontend Testing
Frontend tests are classified into the following levels:
- Unit tests: From the test, start to create a function.
- End-to-end tests: These tests verify that the flows a user follows work as expected, for example: loading a web page, logging in, verifying email notifications, and online payments, validating that these flows are done and that they work correctly.