To customize the appearance and/or behavior of an AEM Communities component on the client-side, there are several approaches.

Two major approaches are to overlay or extend a component.

Overlaying a component changes the default component and affects every reference to the component.

Extending a component, being uniquely named, limits the scope of changes. The term 'extend' is used interchangeably with 'override'.

Overlays

Overlaying a component is a method of making modifications to a default component and affecting all instances which use the default.

The overlay is accomplished by modifying a copy of the default component in the /apps directory, rather than modifying the original component in the /libs directory. The component is constructed with an identical relative path, except 'libs' is replaced with 'apps'.

The /apps directory is the first place searched to resolve requests, and if not found, the default version located in the/libs directory is used.

The default component in the /libs directory must never be modified as future patches and upgrades are free to alter the /libs directory in any manner necessary while maintaining public interfaces.

This is different from extending a default component where the desire is to make modifications for a specific use, creating an unique path to the component and relying on referencing the original default component in the /libs directory as the super resource type.

Extensions

Extending (overriding) a component is a method of making modifications for a specific use without affecting all instances which use the default. The extended component is uniquely named in the /apps folder and references the default component in the /libs folder, thus a component's default design and behavior are not modified.

This is different from overlaying the default component where the nature of Sling resolves relative references to the apps/ folder before searching in the libs/ folder, thus a component's design or behavior is modified globally.

Javascript Binding

The HBS script for the component must be bound to the JavaScript objects, models and views, which implement this feature.

The value of the data-scf-component attribute may be the default, such as social/tally/components/hbs/rating, or an extended (customized) component for customized functionality, such as weretail/components/hbs/rating.

To bind a component, the entire component script must be enclosed within a <div> element with the following attributes:

data-component-id="{{id}}"
resolves to the id property from the context

data-scf-component="<resourceType>"
the sling:resourceType identifying the Javascript used to render the content

Custom Properties

When extending or overlaying a component, it is possible to add properties to a modified dialog.

All properties set on a component/resource can be accessed by referencing the property keys in the handlebars template:

{{properties.<property_name>}}

Skinning CSS

Customizing components to match the overall theme of the website can be achieved by 'skinning' - changing colors, fonts, images, buttons, links, spacing and even positioning to a certain extent.

Skinning can be achieved by selectively overriding the framework styles or by writing entirely new style sheets. The SCF components define namespaced, modular and semantic CSS classes that affect the various elements that make up a component.

Include the stylesheet in a client library folder (clientlibs) for your site and make sure it is included from your templates and pages with ui:includeClientLib.

Redefine the CSS classes and rules that you have identified (#2) in your style sheet and add styles.

The custom styles will now override the default framework styles and the component will be rendered with the new skin.

Caution:

Any CSS class name that is prefixed with scf-js-*has a specific use in javascript code. These classes affect the state of a component (for example, toggle from hidden to visible) and should neither be overriden nor removed.

While the scf-js-* classes do not affect styles, the class names may be used in stylesheets with the caveat that, as they control the states of elements, there may be side effects.

Extending Javascript

To extend a components Javascript implementation, you need only

create a component for you app with a jcr:resourceSuperType set to the value of the extended component's jcr:resourceType, e.g. social/forum/components/hbs/forum

examine the default SCF component's Javascript to determine what methods need to be registered using SCF.registerComponent()

either copy the extended component's Javascript or start from scratch

extend the method

use SCF.registerComponent() to register all methods with either the defaults or the customized objects and views.

Script Tags

Script tags are an inherent part of the client side framework. They are the glue that helps bind the markup generated on the server side with the models and views on the client side.

Script tags in SCF scripts should not be removed when overlaying or overriding components. SCF script tags auto created for injecting JSON in the HTML are identified with the attribute data-scf-json=true.

Clientlibs for SCF

The use of client-side libraries (clientlibs), provides a means of organizing and optimizing the Javascript and CSS used to render content on the client.

The clientlibs for SCF follow a very specific naming pattern for two variants, which vary only by the presence of 'author' in the category name:

Clientlib Variant

Pattern for Categories Property

complete clientlib

cq.social.hbs.<component name>

author clientlib

cq.social.author.hbs.<component name>

Complete Clientlibs

The complete (non-author) clientlibs include dependencies and are convenient for including with ui:includeClientLib.

Author Clientlibs

The author version clientlibs are stripped down to the minimal Javascript necessary to implement the component.

These clientlibs should never be directly included, but instead are available to embed into other clientlibs, which are handcrafted for a site.

These versions are found in the SCF libs folder:

/libs/social/<feature>/components/hbs/<component name>/clientlibs

For example

client folder node : /libs/social/forum/hbs/forum/clientlibs

categories property : cq.social.author.hbs.forum

Note: while author clientlibs never embed other libraries, they do list their dependencies. When embedded in other libraries, the dependencies are not automatically pulled in and must be embedded as well.

The required author clientlibs can be identified by inserting "author" into the clientlibs listed for each SCF component in the Community Components guide.

Usage Considerations

Every site is different in how they manage client libraries. Various factors include:

Overall Speed : Maybe the desire is for the site to be responsive, but it is acceptable for the first page to be a little slow to load. If many of the pages use the same Javascript, then the various Javascripts can be embeded into one clientlib and referenced from the first page to load. The Javascript in this single download remains cached, minimizing the amount of data to download for subsequent pages.

Short Time to First Page : Maybe the desire is for the first page to load quickly. In this case, the Javascript is in multiple small files to be referenced only where needed.