## Milestone Overview

### Goal

Create a shared component with a complex data model based on a document.

### Estimated Time to Complete

30 minutes

### Summary

In the [previous milestone](🔗), you created an advanced component model using "content type mapping". The downside of this approach is that all content is contained within a page context (inline) and cannot be shared. In this milestone you will explore the possibility of creating a document as a stand-alone sharable piece of content (stored in a document), which contains all the data that can be referenced, and therefore shared, across multiple components on different pages and even in multiple channels.

This milestone is derived from the following tutorial: [Content-Driven Component](🔗). Check it out for more detailed information.

For this approach you will need to create a component with only "simple properties". This marks a component as a "shared component".

## Banner Component

In this milestone you will re-create the same banner component (from a frontend point of view) but this time you will implement the backend as a shared document-driven component.

### Create a Document Type

Create a document type with the same fields as the field group you created in the [previous milestone](🔗). Navigate to the _Content_ app, select _Content types_ from the dropdown, select the _Bloomreach (brxsaas)_ namespace, and create a new document type named: "BannerDocument".

The name does not really matter since this will be mostly a technical name and can be changed to a more editor-friendly "display" name. We do need to remember the technical name "BannerDocument".

Using the [Content Type Editor](🔗), add the same fields to the "BannerDocument" document type as you added to the field group type in the previous milestone:

textTextRich Text Editor
imageImageImage Link
ctalinkCTA LinkLink
ctalabelCTA LabelString

Alternatively, if yo prefer using the [Content Type Management API](🔗) instead of the UI, send a [PUT request to the Content endpoint](🔗):

Use the following JSON payload:

Once the document type is created, stay in the _Content_ app but select _Documents_ in the dropdown in the top left. Create a new instance of the BannerDocument type in your channel’s content tree (it doesn't really matter where, but remember the location) as an example so that you can use the data of the document within the components in the next section.

Navigate to the [Site development app](🔗), select your developer project, navigate to the _Components_ section, and create a new component: "Shared Banner".

NameShared Banner
Content type(make sure to leave this empty)
  • `ctype` is the mapping attribute required to do the frontend component mapping

  • `contentType` is left empty because we are not creating a content type mapped component.

On the component's _Properties_ tab, select _+ Property_ and add a new "content path property" to the component property model.

In the _Name_ field enter "document" and in the _Label_ field enter "Banner Reference":

With this property we are able to create a reference to any BannerDocument instance within the channel’s content folder tree. This means that multiple component instances can point to the same BannerDocument instance, creating a shared document driven component. The BannerDocument instance will have its own publicatiow workflow so that means that whenever the BannerDocument instance is changed and published its data will be reflected in each component instance referencing the BannerDocument!

If you prefer using the [Site Management API](🔗) instead of the _Site development_ app, send a [PUT request to the Components endpoint](🔗):

Use the following JSON payload:

Navigate to the _Experience manager_, select your channel (make sure your development project is selected), and add a new instance of the Shared Banner to the home page.

Click inside the component on the page to open the component editor in the right drawer. Set the _Banner Reference_ field to the Banner Document you created earlier:

At this point the component is still displaying _Component "SharedBanner" is not defined_. Let’s create the frontend component by copying the code from milestone 5, `Banner.jsx`, to `src/components/SharedBanner.jsx` and modifying the component in such a way that instead of getting the data from the component content, it now will retrieve if from the document reference.

Create the file `src/components/SharedBanner.jsx` with the following code:

Don’t forget to import SharedBanner in `src/App.js`:

And add it to the `BrPage` mapping:

The SharedBanner component now points to a BannerDocument and uses a referencing strategy for retrieving the data.

One more little thing is missing here. Let’s add a way to edit the content directly within the _Experience manager_ rather than needing to switch to the _Content_ app. You can use the `BrManageContentButton` to achieve this.

Modify your SharedBanner component to display the orange Manage Content Button in your component.

  1. Import `BrManageContentButton` from `@bloomreach/react-sdk`.

  2. Add relative positioning to the style of the component's outermost `div` element.

  3. Insert the `BrManageContentButton` element within the same `div`.

After the above modifications, your code should look as follows:

The result is that the orange Manage Content button is displayed at the top right corner of your component. Click on the button to edit the BannerDocument directly within the _Experience manager._

All source code of this milestone can be found at:


## Best Practises & Extras 💡

A best practice for selecting the BannerDocument reference is to limit the picker selection only to BannerDocuments. This can be achieved by setting extra properties on the document property through the _Site developer_ app with the "Picker selectable node types":