Skip to main content

Client architecture

The different layers of our client-side architecture are shown in the diagram above:

Coko client

@coko/client (which under the hood brings together all the pubsweet client-side libraries, as well as some extra niceties) will take care of most of the heavy lifting when it comes to infrastructure. The client needs to be fed the routes and the theme, and it will take care of the theme being provided in all your components, mounting react on the root component, webpack compilation and more. Check the client docs for more details.

Theme

This is pretty straightforward. All the theme values and application-wide overrides that apply to your components need to exist here. The theme is a single javascript file that can be named whatever you want (but is by convention named theme.js). You can spread your theme code across mutliple files, as long as it all comes together in a single export at the end.

Router

The router (by convention a single file called routes.js) will map the different routes in your app to pages. It should only interact with pages (as defined below) and not with UI components directly.

Pages

Pages are react components that wrap the UI react components and make sure the UI's props are populated correctly. They essentially act as intermediaries between the UI and anything else. Some common tasks that would happen in pages are:

  • Graphql queries, mutations and subscriptions
  • Accessing configuration options
  • Accessing environment variables
  • Interaction with localstorage
  • Reading permissions

It is the page's responsibility to perform any necessary data manipulation and pass only the minimum amount of information needed to the UI.

It is most common that you'd have a single page component for each actual page of your app.

UI

These are the react components that take care of the UI. They are "dumb" in the sense that they do not know anything about their environment, they only know their props. For example, a function that gets passed to be performed on a click could be a server call, a localstorage interaction or a console.log. The UI components do not care about that, they just run the function you passed through the props.

No interaction should happen outside of their props. Any necessary interaction should bubble up to the page component.

All UI components, from the smallest icon to large scale components, should be developed and documented in storybook. Their interactions with parent components or the page component should be mocked in the component's stories file.