Bootstrapping a NextJS + Apollo Frontend

Posted: 16 February, 2020 Category: rough notes Tagged: nextjsapolloreact

This is a followup post to this other one. The project is still under construction / WIP. Rough notes on learnings / (mis)understandings / other self-learning goodness thus far:

Learnings

  • nextjs is NOT react, it's a react framework by @zeit. Unlike client-side-rendered apps (CSR) such as those built via createreactapp, nextjs is SSR (server-side-rendered) react. That said, it supposedly only uses the SSR when needed (eg first load, for faster time-to-paint and time-to-interaction) then flips to CSR once the client has all the files it needs to take over.

    • installing all of react, react-dom, next yields nextjs.
  • if using a cooked css lib like reactstrap for frontend styling

    • add bootstrap, reactstrap => react bootstrap 4. (Then it it might bleat about jquery, popperjs peer deps; if so, add those.)
  • if using the raw css library like bootstrap, bulma for frontend styling

    • add node-sass bulma (using bulma as ex.)
    • create top level folder, eg /styles folder and within it your core css/scss file for customizing and importing the css library of your choice. e.g. a theme.scss file to customize bulma. You get the general idea.
  • loading css

    • dealing with styling will force you to make acquaintances with the next.config.js file. All you really need to know about it at this point is that es6 style imports/exports DON'T WORK IN THIS FILE. You have to require stuff in and module.exports stuff out.
    • to support importing and loading of css files, + @zeit/next-css. See more about that here
    • to use (import) .scss files, you need node-sass, and consequently you'll need @zeit/next-sass.
    • at this point, to use both css and scss => to use multiple plugins => you now need next-compose-plugins, so install that and wire it into ur next.config.js file too. Interestingly, this is NOT by the @zeit folks; to wit: on the plugin's readme page it literally says:

      Provides a cleaner API for enabling and configuring plugins for next.js because the default way next.js suggests to enable and configure plugins can get unclear and confusing when you have many plugins.

  • other interesting css/ux stuff

  • Apollo-graphql setup

    • You basically want to install @apollo-client, which is a "fully-featured caching GraphQL client with integrations for React, Angular, etc...". It takes the place of libs like @apollo/react-hooks, apollo-cache-in-memory etc. Don't use the litany of libs found in tutorials up to this point in time as those libs will be deprecated at some point. Bonus: Apollo also supports type definitions for TypeScript out of the box, so you don't need to run around installing */types libs :-)
    • You also need to install graphql-tag, mainly for turning template strings into graphql ASTs (or more simplistically, the ability to write your gql queries along with your other bits of code).
    • You will need isomorphic-unfetch to make (graphql) http requests on both server and client side.
    • to tie all these things together, you need to create a HOC that uses the apollo client and makes a centralised store of query result data available to its child components.

      • The standard way of doing this is via the withApollo HOC, which you'll need to install next-with-apollo to get.
      • You'll want to create your own instance of this HOC using your instance of apollo-client, uri pointing to your own graphql api etc. Common nomenclature for the resulting HOC is withData and all this wiring is generally placed in a top-level /lib folder in your sourcetree).
      • Finally, wrap data-needing components in the withData HOC, eg: export default withData(MyComponent)... Follows you can do so wih the top-level <App> component. If you don't want to selectively apply the HOC, you can go nuclear and bake it directly into /pages/_app.js.
  • the next-apollo handshake (how it works)

    • Next added a new lifecycle method to React: getInitialProps, within which apollo's getDataFromTree method is called:

      getDataFromTree takes your React tree, determines which queries are needed to render them, and then fetches them all. It does this recursively down the whole tree if you have nested queries. It returns a promise which resolves when the data is ready in your Apollo Client store.

    • That said, to get a sense of what you're being abstracted from, see here: of note is the fact that the raw client is instantiated for each request.
    • For sending bearer tokens and other headers, you'll need to install apollo-link-context. See here. It's a Lerna proj so even the github is apollo-link, the pkg you really want to install is the -context sub-package.

Phase II: Frontend

Build authed UI

  • impl nextjs or nuxtjs for FE
  • choice: nextjs. Larger ecosys, easier to recruit. Can use nuxt for the corp site, hopefully.
  • site comes up
  • add css + ui lib going with bulma Tasks palette: tasks palette general palette: general palette
  • impl basic layout with example menubar
  • impl apollo graphql client

    • impl a withApollo HOC
    • impl a withContext HOC for sending the bearer tokens (hardwired token - get from manual login)