Create a Compony-component

Uploading your component to the platform and making it public, doesn't mean it will be compatible for your future projects. Only components that are self-independent will be usable by others, or by yourself in future projects.

So how do we make a component self-independent?


Color agnostic CSS #

When downloading a component from someone else, you will get a black & white sketchbook, where you can define your own colors. Because If you would create a green component, and someone else comes along and plugs it in to their blue project, things are going to get out of hand really quickly.

This means that your color definitions should all become gray-values, before you commit them to the platform.

// This:
.selector {
  color: $blue;

// Should become this:
.selector {
  color: #333;

NOTE: Please make sure that the different parts of your components have enough contrast when changing the colors to gray-values.


Font agnostic CSS #

When downloading a component from someone else, you don't want to use random fonts. Because otherwise that would mean that each component would require another font. And again, this would get out of hand quite quickly.

Fonts are generally defined in the _global component. Therefor, please remove any CSS-declarations around fonts:

// All of these declarations are not welcome in contributed components
.selector {
  font-family: "Lato";
  font-weight: 400;
  font-weight: bold;
  font-style: italic;



If your component has different font-sizes, it's fine to use the font-size declaration, as long as you keep it in rem and not hardcode it in pxRem's will translate better across different fonts by default. Please use 1 rem as a default, and try to keep variations to a minimum



If you really want to add a font to a component, Creating a font-component is also a possibility! A font component would be the exception to this rule. Example component: the Montserrat font 


Variable free Sass #

Your component should work, without relying on variables defined in other components.

This means that your Sass can't rely on variables or mixins defined in:

  • Sass-essentials
  • your global component
  • other components



Using global breakpoints made a lot of sense, but it has become more of a common practice than a good practice.

An example: If component-a should break on 40rem and component-b should break on 42rem, then why would you define both breakpoints in the _global component?

We encourage component-based variables for breakpoints. (a component example: form-item--radiobuttons)

So your Sass could look like this:

@import "sass-essentials";

$bp-s: 30rem;
$bp-m: 50rem;

.label-text {
  position: relative;
  @media(min-width: $bp-s) {
    padding-right: 2rem;
  @media(min-width: $bp-m) {
    padding-right: 4rem;



Don't extend in Sass, it creates an anti-pattern in CSS, and it links components together in a way that's just not scalable.



An easy way to test this is to remove this:

@import 'sass-essentials';

on top of your sass file and see if Gulp can still compile the CSS.


Twig blocks #

{% block before %}{% endblock %}

<div{{ attributes.addClass(classes) }}>

  {{ title_prefix }}

  {% block title %}
    {% if not page %}
      <h2><a href="{{ url }}">{{ name }}</a></h2>
    {% endif %}
  {% endblock %}

  {{ title_suffix }}

  {% block content %}
    {{ content }}
  {% endblock %}


{% block after %}{% endblock %}

Required block statement

In every template there should be a before block statement, so templates that are extending can have a way of adding libraries.

Using block statements is heavily recommended (Docs: Twig-blocks)


Clear naming

Block statements follow a naming convention that is based upon the naming of the variable being printed inside. So if you are wrapping {{ content }} in a block, then the name of the block should be content as well.

No custom theme name #

The convention for components on the platform is that they are built for a theme that is named compony.



So when writing functions inside your-component.theme file, please change the name of your custom theme to compony, before contributing a component.

So not this:

function my_custom_theme_preprocess_node(&$variables, $hook) {
  // custom code

but this:

function compony_preprocess_node(&$variables, $hook) {
  // custom code



When attaching a library to a component, please make sure you link to the library with the compony theme name.

So not this:

{% extends 'node.html.twig' %}

{% block before %}
  {{ attach_library('my-custom-theme/node--blog--teaser') }}
{% endblock %}

But this:

{% extends 'node.html.twig' %}

{% block before %}
  {{ attach_library('compony/node--blog--teaser') }}
{% endblock %}


Use the default Gulp config #

Within your project you will have changed your gulpfile.js/project.config.js to suit your project.

Before you contribute your component, you should run gulp with the project.config.js containing the default settings. You can copy those settings from the documentation.

Components on the platform should have their dist folders included with them. Therefor, please remove the dist folder from your component, so Gulp can regenerate it, without containing too much stuff such as mapping files.