We use cookies to understand how this site is used. You can accept or reject them — see our Cookie Policy for details.

Installation

Install the package

bash
npm install srcdev-hair-treatments

Import the styles

Two stylesheets ship in dist/: the component's own CSS, and a set of colour tokens it reads from. Import both once, globally, in your app's entry point or global CSS:

css
@import "srcdev-hair-treatments/dist/style.css";
@import "srcdev-hair-treatments/dist/tokens.css";

tokens.css defines the four semantic colour ramps the component uses: --brand-00 through --brand-10, plus --success-*, --warning-* and --error-*. Skip this import and provide your own values instead if you want the widget themed to match your brand from the start — see Theming.

Copy the images

Hair type and colour swatches can show real photography — the package ships a full set of default images, but they need to be served from your own app's public/ directory, not read from node_modules. Add a script to your package.json and run it once after install:

json
"setup:assets": "cp -r node_modules/srcdev-hair-treatments/public/images/. public/images/"

Wire it into a postinstall hook so it stays in sync on every npm install, picking up any new or changed images on a package update:

json
"postinstall": "npm run setup:assets"

See Theming → Images for overriding these with your own photography per option.

Register the plugin

createHairTreatments() is a Vue plugin that provides a default config to every TreatmentConsultant instance in your app. Passing a config here is optional — you can also pass one directly as a prop per-instance (see Configuration). It can also carry your license key so you don't have to repeat it per instance — see Licensing.

ts
import { createApp } from "vue"
import { createHairTreatments } from "srcdev-hair-treatments"
import App from "./App.vue"

const app = createApp(App)
app.use(createHairTreatments())
app.mount("#app")

Use the component

vue
<template>
  <TreatmentConsultant @complete="onComplete" />
</template>

<script setup lang="ts">
import { TreatmentConsultant } from "srcdev-hair-treatments"
import type { ConsultationSelections } from "srcdev-hair-treatments"

function onComplete(selections: ConsultationSelections) {
  console.log(selections)
}
<\/script>

Nuxt

Register the plugin under app/plugins/ (not a root-level plugins/ directory — Nuxt 4's default srcDir is app/, and a plugin outside it silently won't register):

ts
// app/plugins/hair-treatments.ts
import { createHairTreatments } from "srcdev-hair-treatments"

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.use(createHairTreatments())
})

Add both stylesheets to nuxt.config.ts's css array, and wrap the component itself in <ClientOnly>TreatmentConsultant is not SSR-safe. Full details in SSR & ClientOnly.

Plain HTML — no build step

No Vue app, no bundler? A separate dist/embed.js bundle ships everything needed — Vue included — so a plain HTML page can embed the consultation with a <div>, a stylesheet link, and one <script> tag. Loaded from a CDN like jsDelivr, the URL is pinned to a package version, so there's nothing to cache-bust when a new version ships — just bump the version in the URL when you want it.

html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/srcdev-hair-treatments@1.1.3/dist/embed-style.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/srcdev-hair-treatments@1.1.3/dist/tokens.css" />

<div data-hair-treatments data-license-key="YOUR_LICENSE_KEY"></div>

<script
  type="module"
  src="https://cdn.jsdelivr.net/npm/srcdev-hair-treatments@1.1.3/dist/embed.js"
></script>

Every element on the page matching [data-hair-treatments] is mounted automatically once the script loads — nothing else to write. The version above, 1.1.3, is read from this site's own installed dependency, so it's always current — copy it as-is, or replace it with whichever version you've pinned to yourself. See Licensing for where the license key comes from.

Pass configuration per-instance with a JSON-encoded data-config attribute — see Configuration for the shape it accepts:

html
<div
  data-hair-treatments
  data-license-key="YOUR_LICENSE_KEY"
  data-config="{"text": {"heading": "Find your perfect colour"}}"
></div>

There's no Vue app here for @complete/@change to hook into, so the embed bundle re-dispatches them as native CustomEvents on the mount element instead — listen with addEventListener:

js
document
  .querySelector("[data-hair-treatments]")
  .addEventListener("hair-treatments:complete", (event) => {
    console.log(event.detail) // ConsultationSelections
  })