Janis is the codename for the software that renders alpha.austin.gov for web browsers. It is a working prototype of static site generation front-end and decoupled CMS architecture.
Janis uses data provided by the CMS API service, Joplin, along with the React components to generate a static-progressive website.
In order to run Janis locally you need to install Docker. Our team uses Docker for Mac.
Once Docker is installed and you've cloned the code from this repository, you can run the "serve-local" Shell script below to spin up a Docker container and install dependencies within a virtualized environment that replicates the production environment in our Heroku deployment.
In order to develop locally, you will need to have installed these development tools.
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
brew install yarn
Clone the repository and navigate into the newly downloaded directory.
git clone git@github.com:cityofaustin/janis.git
cd janis
Install Janis dependencies.
yarn install
npm install
To run with Joplin Data
cp template.env .env
yarn start-local
yarn start-staging
yarn start-prod
yarn start-pr
As a static build To run the site locally as a static build, the way it works in production, see the Static build script section below.
This work began under the Austin Digital Services Discovery Project. Design, Technology, and Innovation Fellows worked in partnership between two City departments, Communications Public Information and Communications and Technology Management.
We set out to learn what’s working for other government service providers, then embark on an iterative research, prototyping, and testing process to identify new designs, methods, and technologies.
More high level information about the project from content strategy, user research and design, and development teams is continually updated on our project page.
Janis is one piece of a bigger project around content management and technology platforms for the City of Austin.
To manage our roadmap and upcoming issues, we're using a dedicated Github repo, called TechStack, for project management along with Zenhub project boards.
The design team uses sketch to mock up wireframe and high fidelity comps. The most up to date files can be linked here from Google drive. The parent file for current public interface/janis design files is https://drive.google.com/drive/folders/1J1AXm9bDgT0kO_2lugg4mnV4koZHpDO-?usp=sharing.
Here are some high-level notes about the open source technologies we are using for this project.
For more information about the concepts and architectural decisions guiding this work, take a break from this README and check out some of what we have written on Medium and our project page:
This project uses React-Static as a base framework for building static-progressive React applications and websites. It's designed with considerations for SEO, site performance, and user/developer experience.
This project uses React-Intl to format dates and numbers and handle translations of static content. Some details of our current implementation to be aware of follow:
the formatMessage() react-intl API method will return unescaped HTML. We can utilize this method, alongside the dangerouslySetInnerHTML property available to React elements, to render translations of trusted content which include HTML. Note translated content cannot include React Components (see note below for rendering React Components with translations). Also note that the corresponding FormattedMessage Component will NOT return unescaped HTML.
import { defineMessages } from 'react-intl';
const messages = defineMessages({
some_message_key: 'some message with html content and a <h1>{variable}</h1>'
})
...
<div dangerouslySetInnerHTML={{ __html: intl.formatMessage(messages.some_message_key, {variable: 'variable definition'}) }}/>
the FormattedMessage react-intl component will parse React components from the values property. We can utilize this method to render translations which have React components as parameters.
<FormattedMessage
id="misc.workInProgressClipped"
values={{
citySiteLink: (
<ExternalLink to="http://austintexas.gov">
austintexas.gov
</ExternalLink>
),
}}
defaultMessage="Alpha.austin.gov is a new website and a work in progress. For the full City of Austin website, visit {citySiteLink}."
/>
To simplify management of our static translation ids, we use babel-plugin-react-intl-auto. This plugin allows simpler translation definitions and automatically generates translated content ids namespaced to module export names, file paths, or a combination based on our babel react-intl-auto settings.
Translation definitions live in src/js/i18n/definitions.js. Note translations are broken down into separate named exports which can later be moved into their own respective files as static translated content increases. When this is done, be sure to maintain the export name to not have to update imports. Translations are also defined inline when requiring more complex mark-up or JSX (see WorkInProgress component).
docker exec --interactive --tty <janis or janis-build> yarn run build-translations
This plugin will NOT remove previously defined translations which are no longer present in the current app definitions. This clean up needs to be done manually at the moment.
yarn storybook
yarn build-storybook
./scripts/serve-storybook.sh
Prettier is an opinionated code formatter that integrates with most editors. You press save and code is formatted.
To set up Prettier check out their editor integrations.
Following the lead of other government digital services groups (USWDS, UK GDS), we're committing to support browsers that represent > 2% of all site traffic recorded in Google Analytics for visitors to austintexas.gov.
Based on data from 1/1/2018 to 4/16/2018 these are the browsers with > 2% of all site traffic that we commit to support. This list will be reevaluated again when we drop the alpha.
subdomain.
Here are Google Analytics screenshots from data range 1/1/2018 to 4/16/2018.
As this project moves forward, we hope to implement even more comprehensive Browser Support guidelines following the examples of other government agencies like the cfpb.
Our team uses BrowserStack to manually check for device and browser compatibility. Our checklist of devices includes (subject to update):
Mobile
Tablet
Desktop
This will update your container's yarn.lock and package.json files. Your local host machine's yarn.lock and package.json files will also be updated via mounted docker volumes. These local files are versioned and should be checked into git.
Add a package via yarn (https://yarnpkg.com/lang/en/docs/cli/add/)
docker exec --interactive --tty <janis or janis-build> yarn add <package name>
Since we use React-Static as our framework to render our React components as a static progressive website, it's important for us to be able to test the final static build locally. In order to do this, we have a script.
To build and serve
./scripts/serve-build.sh
Your site will be running on http://localhost:8080/
Jest is set up for snapshot testing as well us used for testing our queries. yarn test
will run the tests in src/components
.
If you need to update the snapshots, jest --updateSnapshot
.
We have Cypress set up to run integration tests. Tests are located in janis/cypress/integration. To launch the Test Runner use yarn open-cypress
or npx cypress open
. You must be running janis locally in order to run tests. Here are some example integration tests.
If you would like to update/change the base url used for testing, edit cypress.json
.
We're using BEM for CSS naming and organization
<button class="coa-button coa-button--blue">Button</button>
.coa-LinkList coa-LinkList--boxprimary
.coa-Footer__work-in-progress
Resources:
One advantage for using React components is that we can write reusable HTML-rendering modules that never forget about proper attribute tagging and ARIA labels.
For example, we learned that when we use target="_blank"
on an anchor tag, we should add aria-label="Opens in new window"
and rel="noopener noreferrer"
for security. Now we have a reusable <ExternalLink>
component.
more a11y Resources: