Placement files

This article explains which files are required for building Placements in a client-side implementation.


These files don’t apply if you choose an API implementation.


What is the placement.js file?

The placement.js file is responsible for rendering campaign logic and emitting onImpression and onClickthrough events. These are used to report on campaign performance and engagement. For more information about events, refer to the Impressions and clickthroughs guide .

The code in this file executes once all Simple triggers have been satisfied, and the Coveo Experience Hub has retrieved the content payload from the Content API.

The Experience Hub only calls the content API if the Simple triggers have been satisfied. Therefore, declaring any conditions upfront as Simple triggers not only helps simplify your Placement implementation but also potentially saves network requests.

Example usage

Here is a simple example that takes over a hero banner, making it available to be dynamically targeted by campaigns that apply different messaging, images, and links:

const React = require('preact')
const {
} = require('@qubit/utils/dom')()

module.exports = function renderPlacement ({
  elements: [target]
}) {
  // The onRemove hook allows you to register any cleanup functions such as removing event listeners
  // This is particularly important if you have a single page app, as it allows you to prevent side effects carrying over between virtual page views

  // We'll create a dummy element here that we will use to track who saw the campaign
  // Using the same element regardless of content ensures we are consistent in our tracking
  const element = document.createElement('div')
  insertBefore(target, element)

  // all onImpression when the element enters the viewport
  // This ensures you are reporting on people who have seen the banner
  // Calling onImpression upfront helps to ensure you don't unintentionally exclude visitors when performing an AB test
  onEnterViewport(element, onImpression)

  // If a campaign is running, you may receive some content to render
  if (content) {
    const { message, image, link } = content

    // Using JSX to render markup has a number of benefits. You get nice syntax highlighting
    // And it compiles much more efficiently than strings which helps keep bundle size down
      <div className='Hero' style={{ backgroundImage: `url(${image})` }}>
        <h2 className='Hero-title'>{message}</h2>
        <a href={link} className='Hero-button' onClick={onClickthrough}>
          Click here
    // After rendering our new banner, you can hide the old one
    style(target, { display: 'none' })

  } else {

    // It is still important to set up `onImpression` and `onClickthrough` when there is no content
    // That way you can compare outcomes and engagmenet with and without content
    onEvent(target.querySelector('a'), 'click', onClickthrough)

You can find more examples of common kinds of placement builds here. It is recommended that you explore them, as different placements, particularly Product recommendations placements, may require additional reporting.


What is the placement.css file?

The placement.css file is used to inject CSS into the page when developing a placement. It’s recommended that you use your placement.css to inject CSS, not least because the code in this file is optimized and compressed for performance.

The CSS rules defined in placement.css are injected into the page only if your Simple triggers.


Because all experience CSS code is compiled using the open source LESS compiler, you can make use of all of the great features that LESS offers, including:

  • Variables

  • Nested rules

  • Arithmetical operations

  • Mixins


What’s the package.json file?

The package.json file contains metadata about your placement, including package dependencies.

For more information about packages, see Packages & code re-use.

If you use Coveo Qubit CLI, the package.json also stores some additional metadata that allows the CLI to distinguish between the placements stored on your local file system.

Coveo Qubit CLI will also install the extra dev dependencies and configuration below that will help keep code consistency and organization.


"devDependencies": {
  "@qubit/jest": "^1.4.0",
  "healthier": "^4.0.0",
  "jest": "^26.6.3",
  "prettier-standard": "^16.4.1"
"healthier": {
  "globals": [
"jest": {
  "transform": {
    ".*(.js|.css|.less)$": "@qubit/jest"
  "transformIgnorePatterns": []
"scripts": {
  "format": "prettier-standard --fix",
  "lint": "healthier",
  "test": "jest --coverage"


What’s the placement.test.js file?

The placement.test.js file is currently only available if you create your placement using the Coveo Qubit CLI and will not be pushed to the UI. It’s particularly useful if you keep your placement code locally or in a repository.

Running tests

The placement.test.js file comes with some minimal tests that check whether the events are being called correctly, which is crucial for the health of your data. It’s recommended that you implement and run these tests, as well as add any extra ones that ensure your placement is always working as expected.

Our test runner is jest, and you can run your tests with the npm test command.

You can learn more about our configuration in the package.json section and more about unit testing here.