-
Notifications
You must be signed in to change notification settings - Fork 5
Core principles
The JustFix.nyc Tenant Platform (sometimes called "tenants2") was designed with the following principles:
-
Progressive enhancement. JustFix services are used by tenants on a wide variety of devices and in a wide variety of contexts. For example, many low-income individuals may need to use our services on computers with ancient browsers in housing court, or they may use older cell phones with outdated browsers.
Due to this, we strive to build the platform in such a way that a baseline experience works on virtually any browser, and may optionally become progressively enhanced to harness the capabilities of the user's device and network connection.
At an implementation level, this means we use a combination of server-side rendering (SSR) with JavaScript feature detection to ensure that users are given the best possible experience. For more details, see the Architecture section.
-
Seamlessness. End-users should not experience layout instability or "jank" when using the site. For example, the initial page load should not result in different pieces of content popping in or out of view, potentially derailing a user's train of thought and causing anxiety.
-
Accessibility. The platform should be usable by anyone, regardless of any visual, motor, or cognitive impairments.
This means, for example, that the site needs to be fully usable via the keyboard, screen readers, or other assistive technologies (ATs).
-
Resiliency. The platform is designed to work when third-party services may be down or unavailable. As a corollary, whenever possible, integration with third-party services should be optional, rather than required.
Furthermore, browser environments are quite unpredictable, and it's possible that, despite our best efforts, some browsers may raise unexpected errors when our JavaScript runs. To address this, the site's compatibility mode serves as a kind of safety net, essentially allowing users to opt-in to a JavaScript-free experience.
-
Stability. A suite of unit and integration help ensure that nothing accidentally breaks when we change things.
Furthermore, wherever possible, we use tools like TypeScript and mypy to ensure that the site doesn't accidentally crash. These tools also allow us to more easily understand and refactor the codebase.
-
Security. The platform should be resistant to malicious attacks through the use of best practices such as Content Security Policy. Sensitive data should be protected by two-factor authentication, and other measures should be taken to ensure that users and their data are safe.
To illustrate some of the core principles in action, we can examine the address field used by the platform.
If the user’s JavaScript and the NYC Planning Labs GeoSearch API are working, we present the user with a progressively-enhanced auto-complete experience that is made accessible to assistive technologies via the excellent Downshift component:
However, if either one of these prerequisites isn’t met--or if a network error occurs while the user is using the widget--we try our best to be resilient. So the user sees the baseline user interface, which involves a non-autocompleting address field and an additional set of radio buttons asking for the user’s borough:
Additionally, because geocoding needs to be done after the user submits the form, if the geocoded address is significantly different from the one the user entered, a modal dialog is shown that allows the user to confirm that the geocoded address is correct.
Sometimes core principles can be at odds. For example, consider the hamburger menu at the top-right of the page on mobile devices. When the page first appears, we'd like the menu to be collapsed:
Once the user activates the menu, it should expand:
However, our principle of progressive enhancement dictates that we shouldn't assume the user has JavaScript available, which means that, in order to for the content of the hamburger menu to be accessible, the hamburger menu needs to be expanded before the page has loaded and activated its JavaScript.
However, this violates our principle of seamlessness, as many users loading the page will see the hamburger menu expanded for a split-second and then immediately collapse. That's janky.
One way to balance these conflicting principles is by recognizing that the vast majority of users will have JavaScript available. If we optimize for this case (by displaying the hamburger menu collapsed while the page is loading) but allow users who are left behind to indicate that things aren't working for them, we can potentially preserve both principles.
We currently do this by leveraging a feature we call compatibility mode. This feature is intended as a general-purpose resiliency mechanism in the case of unexpected JavaScript errors, but we can also use it to balance progressive enhancement with seamlessness.
By default, the user isn't in compatibility mode, so we send initial page content assuming that JavaScript will eventually load in the user's browser. However, if the user's browser has JavaScript disabled or our main JavaScript bundle doesn't load, the user will see the following at the bottom of their screen:
If they click "Activate compatibility mode", the page will re-load, but with the hamburger menu (and possibly other page elements) expanded, allowing the user to access the full functionality of the site.