Skip to content

Adding arrow rows

Amogh S edited this page May 17, 2021 · 3 revisions

Adding arrow rows

Arrow is a react component library intended to be used by Quintype frontend apps. It gives (among other things) pre-styled "rows" that frontend apps can use to display stories. Please refer the arrow docs for more details, installation and usage guides.

Setting collection layout

  • Create config/template-options.yml file. Bold will use this file to set the collection layout. Sample config/template-options.yml file:
collection-layouts:
  - name: ArrowFourColGrid
    display name: Arrow Four Col Grid
    options: []
  - name: ArrowThreeColSevenStories
    display name: Arrow Three Col Seven Stories
    options: []
  - name: ArrowTwoColFourStories
    display name: Arrow Two Col Four Stories
    options: []
  • These templates should show in Bold > Collections > manage as a dropdown

  • Try selecting a template here and publish. You should be able to see that template in the API response of api/v1/collections/<collection-name> under items > associated-metadata > layout

Next steps

  • Follow Arrow's integration guide
  • In your app, create wrapper components around arrow rows
  • Add these wrapper components to app/isomorphic/components/collection-templates/index.js, just like non-arrow templates
  • After this step, you should be able to see the arrow rows in the frontend
  • Some Arrow rows display collection of collections. Please make sure a proper depth is set in the appropriate load-data function
  • For better performance, it is recommended to inline the styles of the first row, so that server-side will work properly. Follow the guide below

Improving performance of arrow rows

Malibu uses isomorphic rendering for achieving good performance. Inlining the 1st row's CSS greatly improves the performance. For this reason, Arrow exports the CSS of every component separately in addition to having them in the main JS bundles. For example all styles needed for rendering the arrow component FourColGrid can be imported like this:

import "@quintype/arrow/FourColGrid/styles.arrow.css";
  1. Create separate chunks of all the arrow rows that you'll be using in the app. For example if you plan to use the rows FourColGrid, ThreeColSevenStory and TwoColFourStories, create three new chunks containing the styles of these three rows

  2. To create chunks, add these as entry points to webpack. In the file ./quintype-build.config.js, add them as follows

    const quintypeBuildConfig = require("@quintype/build/config/quintype-build");
    const configObj = {
      ...
      entryFiles: {
        ...
        arrowFourColGridCssChunk: "@quintype/arrow/FourColGrid/styles.arrow.css",
        arrowThreeColSevenStoryCssChunk:
          "@quintype/arrow/ThreeColSevenStory/styles.arrow.css",
        arrowTwoColFourStoriesCssChunk:
          "@quintype/arrow/TwoColFourStories/styles.arrow.css",
      },
    };
    
    module.exports = { ...quintypeBuildConfig, ...configObj };

    If you're using loadable components, this can be given like so

    const quintypeBuildConfig = require("@quintype/build/config/quintype-build");
    const loadableConfigObj = {
      loadableConfig: {
        entryFiles: {
          ...
        arrowFourColGridCssChunk: "@quintype/arrow/FourColGrid/styles.arrow.css",
        arrowThreeColSevenStoryCssChunk:
          "@quintype/arrow/ThreeColSevenStory/styles.arrow.css",
        arrowTwoColFourStoriesCssChunk:
          "@quintype/arrow/TwoColFourStories/styles.arrow.css",
        }
      }
    };
    const modifiedBuildConfig = { ...quintypeBuildConfig, ...loadableConfigObj };
    
    module.exports = modifiedBuildConfig;
  3. next we need to inline the CSS of the 1st row. 1st row because that's what matters to get good initial load times. Add this in the app/server/handlers/render-layout.js file

    import get from "lodash/get";
    import { assetPath, readAsset } from "@quintype/framework/server/asset-helper";
    ...
    const arrowCss = getArrowCss(params.store.getState())
    
    function getArrowCss(state) {
      const layout = get(state, ["qt", "data", "collection", "items", 0, "associated-metadata", "layout"], null)
      switch (layout) {
        case "ArrowFourColGrid":
          return getAsset("arrowFourColGridCssChunk.css");
        case "ArrowThreeColSevenStories":
          return getAsset("arrowThreeColSevenStoryCssChunk.css");
        case "ArrowTwoColFourStories":
          return getAsset("arrowTwoColFourStoriesCssChunk.css");
        default:
          return "";
      }
    }
    function getAsset(asset) {
      return assetPath(asset) ? readAsset(asset) : "";
    }
  4. Pass arrowCss from the previous step to layout.ejs, and add these styles to the html <head>

  5. Check if the styles for the 1st row are being inlined correctly during server side rendering