How to Approach Sitecore Development with SXA
The goal of any SXA project is not to write zero code, or leverage the OOB components as much as possible. The goal is to build a site that can be easily managed by content authors and will be intuitive and consistent when authoring. This should be the goal of any site built with Sitecore or any other CMS platform, but we tend to lose sight of that when looking at new unfamiliar tools.
To help developers get past that newness, I've written up the following to detail how I approach SXA development.
Content Types
Content Types are templates that represent something tangible: They could be data sources for components, or referenced by data sources for components. They could be content managed or imported via integration. Example could be a Product, Article or Location.
In most cases these should exist in their own subfolder of the Site Data folder, though there could be some cases where you want to scope them at the Tenant or even globally for sharing purposes. Think through how they will be used and put them accordingly, and most importantly, leverage tokens when configuring data sources to make them reusable across sites and tenants.
Page Templates
Page templates are templates that can be inserted somewhere under the home node of a site and are usually configured as insert options where it makes sense for content authors. In SXA, page templates are defined at the Tenant level and may be shared across sites within that Tenant.
Page Templates may also be content types, and be used to add additional fields that are content managed and usually surfaced on the presentation through components that know or expect those fields to exist on the page. When this is the case, the best practice is to create a content type template in an SXA Feature and then have your Project level Page Template inherit both the feature content type and the Tenant base Page Type.
Page Designs
While Page Templates define where pages can be inserted and what content is stored at the page level, they should not define the presentation and what components should be displayed for that page. This is because different sites may choose different arrangements of components for the page. That is why it is not recommended to define any presentation on the standard values of your page type templates.
Page Designs are associated with Page Templates, either in the defaults on the Page Designs root node in the site's presentation folder, or can be overridden on an individual page basis. Keep in mind components don't actually go on Page Designs. Page Designs are pointers to a collection of partial designs, which are where components are actually configured.
Partial Designs and Data Sources
While partials are a great way to group commonly used components and layouts, it is important to understand how components on partials bind to their data sources and what is means to for your content types.
By default when you place most components on a partial design the data source will either be in the local data folder for the partial or in the site's "Data Folder" (or shared site's data folder). While these data sources will allow the component to be editable on the partial itself, if may not appear editable on the page where the partial is used. This is because SXA only makes fields that are on the page or local to the page editable when injected by a partial design.
So if you want to use partial designs to allow editing, you need to either bind to page fields themselves or to page local data sources. You can modify any local data source to be page local by changing the data source syntax from "local:/Data/datasourceName" to "page:/Data/datasourceName" where datasourcename is the item you want to bind to. Keep in mind that this data source will not be created automatically, so you should define a branch template for the page template you plan on associating with this page design so the data sources are created automatically for content authors when they insert this page.
The other alternative is to bind to a page field, which can be a custom field defined in the content type your page template inherits from. To do this ensure you component has an empty data source as those are bound to the page itself when rendering. This is how components like Page Content work automatically, but you can take the same approach if your components are expected to bind to page fields or content type fields inherited by your page template.
Using OOB Components, vs creating your own
If the requirement matches an existing SXA component, use it. If you are creating rendering variants to support that requirement, consider naming the variants to mesh with how content authors refer to it. For example if provided designs refer to an element as a hero teaser, which can be rendered using a Promo Component, name your custom variant "Hero Teaser" to promote consistency with the design.
If the component needs to bind to one of your content types and your page template exposes that field, consider using the Page Content component. It automatically binds to the page's data source and you can define a custom variant to expose those fields.
If you end up with an unmanageable amount of variants (more than a handful), consider how to logically group your variants so they will make the most sense to content authors, and then clone the component, choosing a name for the grouping that will be intuitive to the content author. For example, if you have 10 variants for the Promo Component, and five of them are referred to as a "Teasers" consider cloning the promo and calling it a "Teaser", moving the teaser variants to the new component. It is perfectly reasonable to clone the OOB components multiple times, coming up with names that make sense to content authors and then removing the OOB component from the toolbox to avoid confusion.
When you need to go Custom
If the component is a one off, and doesn't need to be content edited, use the HTML component.
If you need to display content from one of your new content types, it probably makes sense to clone and extend one of the OOB components. If your requirements closely match an existing component, then it is probably clear which component to clone/extend. But for many cases, your trying to bind to your custom data sources and there is no real existing component that has a template anything like your template. In these cases you still should consider cloning a component, if for nothing to ensure it is setup an SXA feature, with proper structure around new templates.
But which component should you clone? I typically start with one of the following options:
Rich Text (Reusable) or Promo - Gets a Custom Template and Data Folder and always prompts content author to choose where it's stored. Be sure to specify the option to Copy the template/Don't extend in order to not have the OOB Field in your template, then simply remove it's fields and inherit your content type.
Rich Text - Automatically creates page local data source, so use this one if you just want your content type to be created under the page.
Page Content - As mentioned, these bind to the page by default giving you flexibility, so really consider whether you need to actually clone this in the first place. It is usually only recommended when you're trying to change the name of the component or using it to manage large groupings of rendering variants, but I'll sometimes use this as a base rendering configuration that I'll go edit the data source restrictions and other behaviors since it is lean and defaults to not having a data source.
Page List - You may have a list of things to display in a multi column layout and think this is the component to use, but for most cases, you want a promo. This works great if you're binding to siblings, children or have a fixed set of Item Queries that will be managed by developers, but if you want to give content authors the power to curate and manage the actual items being displayed, you need a custom template with a Multilist or Treelist and should be cloning the Promo instead.
When to go fully custom
If there is no existing component that solves your requirement or if you have specific business logic that can only be implemented in a controller or repository. Even then, guidance would be to support Rendering Variants in your custom components as much as possible to give as much flexibility for defining presentation as possible.
Don't forget to clean up
Removing is just as important as adding functionality to a SXA site. If you leave the toolbox full of components that are never (or should never) be used, leaving them in the site will just add to content author confusion. Remove them from available renderings, leaving just the components that are tested and usable available to them.