## Milestone Overview
Create a page-specific component with a complex data model based on a field group type.
### Estimated Time to Complete
In the [previous milestone](🔗), you created a simple component model using "simple component properties". In this milestone you will create a more complex component data model.
This milestone is derived from the following tutorial: [Create a Page-Specific Component](🔗). Check it out for more detailed information.
Components can have 2 different types of model mappings:
content type (for more advanced purposes)
Take a look at the [Best Practices & Extras](🔗) section below for a guideline on when to use "simple component properties" and when to use "component content type mapping".
Mapping a component model to a content type enables a more complex data model and offers features such as:
Nested field groups
Rich text fields
Custom fields ([custom integrations](🔗) e.g. DAM integrations)
The concept is that you bind a [field group type](🔗) to a component.
Once a component is bound to a field group type, it becomes a [page-specific component](🔗); a page-specific component can only be added to an [experience page](🔗) and not to any "shared containers". That explains the name: (experience) page-specific components
Another way of looking at page-specific components is that these are "inline components" or "page-contained components". You can have a rich data model that is applicable to components but you cannot share these component instances across multiple pages. The benefit is that editors can create these faster and more intuitively. If the component with the exact same content needs to be displayed on a different page it needs to be manually duplicated by the editors.
If you want to use a complex component model that should be shared across multiple pages, you'll find a solution in the next milestone: [Milestone 6 - Create a Shared Document-Driven Component](🔗).
## Banner Component
You will be modeling a "Banner" Component.
Visually it could look like this:
This Banner component will have the following (content) fields:
title : String
### Create a Field Group Type
The first step is to create a new field group type that will serve as the data model for the Banner component.
Make sure to have a [development project](🔗) with the _Include content types_ option enabled. If you did the previous milestones and already have a development project with content types enabled, you can re-use that one.
Navigate to the _Content_ app and select _Content types_ from the dropdown in the top left:
Select the Bloomreach (brxsaas) namespace and add a new field group type:
Name the new field group type "BannerComponentModel":
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 “BannerComponentModel”.
The [Content type editor](🔗) will appear. Add the required fields as described above:
|text||Text||Rich Text Editor|
Click on _Done_ to save the field group type and close the content type editor.
Alternatively, if you prefer using the [Content Type Management API](🔗) instead of the UI, send a [PUT request to the Content endpoint](🔗):
Use the following JSON payload:
### Configure the Banner Component
Once the field group type is created it can be bound to a component. Navigate to the [Site development app](🔗), select your developer project, navigate to the _Components_ section, and create a new component: "Banner".
ctype` is the mapping attribute required to do the frontend component mapping
contentType` is the mapping attribute to bind the field group (data) model to the component
Alternatively, 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:
The "Banner" Component is now available in the component library of the project’s channel. Navigate to the channel preview, make sure your development project is selected in the _For project_ dropdown, and add the "Banner" component to the page:
You will notice that the new component will display the text: _Component "Banner" is not defined_.
But you can already click and edit the component. You will notice that all of the content fields that we defined in the fieldgroup are available for editing:
### Implement the Banner Component Frontend Code
Similarly to the process in [Milestone 4](🔗), map the "Banner" backend component to a "Banner" frontend component.
Copy the following snippet to a `
src/components/Banner.jsx` file :
The following line will get retrieve all of the content:
The JSX markup will, for now, just print the values of the content element:
Don’t forget to update the mapping property in the `
BrPage` element in `
src/App.js` to include the `
Finally, finish the markup:
The component should now render as in the following screenshot:
Please note that we recommend using TypeScript for code auto-completion and easier access to the SDKs functions such as:
Banner.tsx` could look as follows:
All source code for this milestone can be found at:
## Best Practices & Extras 💡
For each content-mapped component, create a new field group and have clear naming conventions. Reuse of content types is fine but be aware that if you change one field group it will impact all of the components which have been bound to that same field group. Therefore, our recommendation is to use a separate field group for each component.
In a component’s data model, it is recommended to use simple properties for display logic such as colors, themes, margins, and anything you need CSS to do the magic, and field groups (content type mapping) for content fields such as titles, images, call to actions, textual content etc. In this milestone 5 example you’ve created a Banner component. If you wanted to provide display and/or layout options such as a background color, alignment, or padding, the best practice would be to provide these as properties of the component model, rather than using the content type mapping.
Navigate to the Banner component in the _Site development_ app and add 3 new properties
backgroundcolor : String alignment : String (dropdown: left, center, right, justify) padding : Integer
Navigate back to the _Experience manager_ and edit some of these properties:
The frontend code that goes with the above rendering: