react-whitelabel

react-whitelabel is a small library that makes it easy to apply run-time white-labeling for React projects.

Installation

react-whitelabel is availabile in the NPM registry.

> npm i react-whitelabel

or

> yarn add react-whitelabel

Usefulness

This library would be most useful in client-side white-labeling situations. For example: the domain name could be used as the "label" so depending on the domain used to access the site, the user would see a different version of the white-label.

Usage

react-whitelabel requires a WhiteLabelProvider be specified with two props: labels and selectedLabel. labels is an object where each key is a "label". selectedLabel is the currently selected white label. selectedLabel must be a key in the labels object.

A WhiteLabelConsumer or withWhiteLabelContext can then be utilized as descendants of WhiteLabelProvider. They provide access to the properties of the currently selected label.

Function Based Example

app.js

import React from 'react';
import { WhiteLabelProvider } from 'react-whitelabel';
import Header from './Header';

import CarLogo from './imgs/car.png';
import TruckLogo from './imgs/truck.png';

const labels = {
    cars: {
        logo: CarLogo
    },
    trucks: {
        logo: TruckLogo
    }
};

export default () => (
    <WhiteLabelProvider labels={labels} selectedLabel={'cars'}>
      <Header />
    </WhiteLabelProvider>
);

Header.jsx:

import React from "react";
import { WhiteLabelContext } from 'react-whitelabel';

export default () => {
    const label = useContext(WhiteLabelContext);
    return (
        <header className="App-header">
          <img src={label.logo} />
        </header>
    );
}

Because the selectedLabel is cars the CarLogo would be rendered in Header in this case.

Example

app.js:

import React from 'react';
import { WhiteLabelProvider } from 'react-whitelabel';
import Header from './Header';

import CarLogo from './imgs/car.png';
import TruckLogo from './imgs/truck.png';

const labels = {
    cars: {
        logo: CarLogo
    },
    trucks: {
        logo: TruckLogo
    }
};

const label = 'cars';

export default class App extends React.Component {
    render() {
        return (
            <WhiteLabelProvider labels={labels} selectedLabel={label}>
              <div className={label}>
                <Header />
              </div>
            </WhiteLabelProvider>
        );
    }
}

Header.jsx:

import React from "react";
import { withWhiteLabelContext } from 'react-whitelabel';

class Header extends React.Component {
    render() {
        return (
            <header className="App-header">
              <img src={this.props.label.logo} />
            </header>
        );
    }
}

export default withWhiteLabelContext(Header);

Which would render the CarLogo in Header.jsx.

Assets

If using webpack with image and css loaders a couple techniques can be applied to automatically prepare the labels structure.

Here we load all the css files in the css subfolder. If the css selectors in the files are prefixed with the label name and a high-level div has its class set to match the current label then styles for the selected label will automatically be applied.

They could use CSS like:

.trucks .header {
    color: green;
}

And:

.cars .header {
    color: green;
}

Images could be loaded like this from an assets/[label] subfolder. The resulting images object would be keyed by the [label] and then the name of the image file. So if we had two files: assets/cars/logo.svg and assets/trucks/logo.svg we could use the following code to load the images.

const images = (ctx => {
    let keys = ctx.keys();
    let values = keys.map(ctx);
    return keys.reduce((o, k, i) => {
        const parts = k.split('/');
        o[parts[1]] = { [parts[2].split('.')[0]]: values[i] };
        return o;
    }, {});
})(require.context('./assets', true, /.*/));

And then inserted into the labels structure:

const labels = {
    cars: {
        ...images.cars,
        name: 'Cars'
    },
    trucks: {
        ...images.trucks,
        name: 'Trucks'
    }
};

So now labels will be something like:

{
  cars: {
    logo: '12345.svg',
    name: 'Cars'
  },
  trucks: {
    logo: '67890.svg',
    name: 'Trucks'
  }
}

Contributing, Bug Reports, Feature Requests, General Questions

For any of the above send an email to Thomas Hintz at <thomas [at] thomashintz.org>.

License

The react-whitelabel project is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version OR under the terms of the MIT license.