In this section, we will learn how to build a simple “Color Picker” app using the Contentstack app framework. This app contains a Custom Field UI location, which provides a native color picker polyfill that Contentstack users can use as an input field.
This step-by-step guide explains how to create a Color Picker app and use it to select color as an input within an entry.
As a first step, you need to create a project directory where you can work in. We will be using the Marketplace App Boilerplate for creating our project.
git clone https://github.com/contentstack/marketplace-app-boilerplate.git color-pickercd color-picker
$ npm install
$ npm start
This hosts your application on http://localhost:3000. We'll later connect to this through the Contentstack web app.
To register your app with Contentstack, log in to your Contentstack account and follow the steps given below:


Next step is to declare where you want the app to appear in the Contentstack interface with the UI location section. Follow the steps given below to configure the Custom Field UI location for our newly created Color Picker app.




On saving, you will be directed to the UI Locations tab. You will see that one location has been configured in the App Locations section.

Now that you have completed configuring your app, you can go ahead and install the app on any stack of your choice.

Congrats, your app is now installed. You will be redirected to the Installed Apps section in the Marketplace.
Now that you have installed the app, you can go ahead and add it to your content type. Go to the stack in which you have installed the app and follow the steps given below:




Now, when you create an entry for that content type, you will see your app in action.
If you see a custom field, it means the app was successfully loaded. Now let's go ahead and complete the implementation.
For the Color Picker app that you are making, you must first install some dependencies. So, on your terminal, type the command below to install the dependencies.
$ npm i reactcss react-color @contentstack/venus-components@1.0.5
$ npm i --save-dev @types/react-colorAdd the Color Picker type to the Type file in /src/common/types/types.ts
export interface ColorPickerData {
showPicker: boolean;
pickerColor: {
r: any;
g: any;
b: any;
a: any;
};
}In the /src/containers/CustomField/CustomField.tsx file, replace the custom field code with the code given below:
/* Import Node modules */
import { useEffect, useState } from "react";
import { SketchPicker } from "react-color";
import reactCSS from "reactcss";
import { InstructionText } from "@contentstack/venus-components";
import { isEmpty } from "lodash";
/* Import our modules */
import localeTexts from "../../common/locales/en-us/index";
import { ColorPickerData } from "../../common/types/types";
import { useAppSdk } from "../../common/hooks/useAppSdk";
import { useCustomField } from "../../common/hooks/useCustomField";
/* Import our CSS */
import "./styles.css";
const CustomFieldExtension = () => {
const appSdk = useAppSdk();
const { customField, setFieldData }: any = useCustomField();
const [stateColor, setColor] = useState<colorpickerdata>({
showPicker: false,
pickerColor: {
r: "108",
g: "92",
b: "231",
a: "100",
},
});
const styles = reactCSS({
default: {
color: {
width: "70px",
height: "30px",
borderRadius: "4px",
background: `rgba(${stateColor.pickerColor.r}, ${stateColor.pickerColor.g}, ${stateColor.pickerColor.b}, ${stateColor.pickerColor.a})`,
},
},
});
const togglePickerVisibility = () => {
setColor((prev) => ({
showPicker: !prev.showPicker,
pickerColor: prev.pickerColor,
}));
};
const closePicker = () => {
setColor((prev) => ({
showPicker: false,
pickerColor: prev.pickerColor,
}));
};
const pickerColorChanged = (colour: any) => {
setColor((prev) => ({
showPicker: prev.showPicker,
pickerColor: colour.rgb,
}));
setFieldData(colour);
};
useEffect(() => {
appSdk?.location.CustomField?.frame?.updateHeight?.(350);
if (!isEmpty(customField) && customField !== null) {
setColor({
showPicker: false,
pickerColor: customField.rgb,
});
}
}, [customField]);
return (
<div className="layout-container">
<InstructionText testId="color-picker-text">{localeTexts.CustomField.instruction}</InstructionText>
<div>
<div className="swatch" role="none" onClick={togglePickerVisibility} onKeyDown={togglePickerVisibility}>
<div style={styles.color} />
</div>
{stateColor.showPicker ? (
<div className="popover">
<div className="cover" role="presentation" onClick={closePicker} onKeyDown={closePicker}>
<SketchPicker color={stateColor.pickerColor} onChange={pickerColorChanged} />
</div>
</div>
) : null}
</div>
</div>
);
};
export default CustomFieldExtension;
In the /src/containers/CustomField/, create a styles.css file and add the custom field CSS with the code given below:
.layout-container {
padding: 5px;
margin: -28px 0;
}
.layout-container .InstructionText {
text-align: left;
color: #647696;
display: block;
font-family: Inter;
font-size: 0.75rem;
line-height: 1.5;
}
.layout-container .swatch {
padding: 5px;
background: #fff;
border-radius: 1px;
box-shadow: 0 0 0 1px rgb(0 0 0 / 10%);
display: inline-block;
cursor: pointer;
}Add new strings to Custom Field object node in locales in /src/common/locales/en-us/index.ts.
CustomField: {
. . .
instruction: "Pick a Color",
},Stop and restart your React project:
$ npm start
Reload the entry page, and now you will see an actual Color Picker loaded into the custom field.

Save any color and reload, and verify if the app is saving data and fetching it on reload.