Adding a Sidebar to the Layout

The Scrivito Example App layout is designed based on UI and UX design research and testing. But one size does not fit all, so the app was built with extensibility and customization in mind. In this tutorial, we will be adding a sidebar to the layout as an example of how to expand or adapt the layout for your own site.

In the “App.js” file, Scrivito.CurrentPage is mounted into the DOM at the top level. You can see this here along with the navigation, error pages and the footer.

In the About the Scrivito Example App article, the “What's the current page?” section explains that the CurrentPage changes as the user navigates the site. “App.js” renders each page by generating a navigation and the current page (or an error page) plus a footer. Since we are using React, everything is a component, and new components can be added with ease.

Copy
export default function App() {
  return (
    <ErrorBoundary>
      <div>
        <div className="content-wrapper">
          <Navigation />
          <Scrivito.CurrentPage />
          <NotFoundErrorPage />
        </div>
        <Footer />
        <CurrentPageMetaData />
      </div>
    </ErrorBoundary>
  );
}

Create the sidebar component 

In this case, we can keep it simple. Since the sidebar does not need any functionality, we can implement it as a function that just renders the (not yet defined) sidebar attribute using  Scrivito.ContentTag.

src/Components/sidebar.js
Copy
import * as React from 'react';
import * as Scrivito from 'scrivito';
function Sidebar() {
  const root = Scrivito.Obj.root();
  if (!root) { return null; }
  return (
    <Scrivito.ContentTag content={ root } attribute="sidebar" />
  );
}

export default Scrivito.connect(Sidebar);

Note that we are always rendering the sidebar attribute of the CMS root object, independently of the CurrentPage. This ensures that there’s only one sidebar common to all pages.

The root object is determined using Scrivito.Obj.root(); this is the Obj whose _path is “/”, and in a default implementation of Scrivito is initially set to the “Homepage” class.

Add the sidebar attribute to the Homepage class

Our sidebar is meant to be filled with widgets, so we’ll add it as a widgetlist attribute to the “Homepage” object class:

src/Objs/Homepage/HomepageObjClass.js
Copy
// Imports
...
const Homepage = Scrivito.provideObjClass('Homepage', {
  attributes: {
    ...defaultPageAttributes,
    showAsLandingPage: ['enum', { values: ['yes', 'no'] }],
    childOrder: 'referencelist',
    footer: ['widgetlist', { only: 'SectionWidget' }],
    logoDark: 'reference',
    logoWhite: 'reference',
    dividerLogo: 'reference',
    facebookAppId: 'string',
    twitterSite: 'string',
    googleMapsApiKey: 'string',
    sidebar: 'widgetlist',      /* ⬅ */
    ...metaDataAttributes,
  },
});
...

Add the sidebar to App.js

Once again to keep it simple, we’ll render the sidebar and the current page in dedicated columns, so they fit on the screen:

src/App.js
Copy
// Other imports
...
import Sidebar from 'components/sidebar';

export default function App() {
  return (
    <ErrorBoundary>
      <div>
        <div className="content-wrapper">
          <Navigation />
          <div className="row">
            <div className="col-md-3">
              <Sidebar />
            </div>
          </div>
          <div className="col-md-9">
            <Scrivito.CurrentPage />
          </div>
          <NotFoundErrorPage />
        </div>
        <Footer />
        <GoogleAnalytics />
        <CurrentPageMetaData />
        <Intercom />
      </div>
    </ErrorBoundary>
  );
}

After reloading the page or restarting the local server, you should see the widgetlist drop zone of the sidebar attribute in your layout. It is a blank gray canvas; try adding some images or text:

Sidebar blank canvas
Sidebar with some content

In the above example, we started with a section widget, then added a divider widget, a text widget, another divider widget and an image widget in a sequence as an example. Starting with the section widget allows the editor to style the section as a whole. You could even require the sidebar to contain only section widgets. How this can be done is explained in detail in the Customizing Widget List Rendering documentation article, check it out.