What I wanted to achieve was a custom select widget, filled with dynamic values, thus not set in the config.yml. The default select widget of the Netlify CMS is very useful though, since it supports search-as-you-type functionality.

I spent some time figuring out how to add a custom select widget to the Netlify CMS with dynamic values. Turned out not to be so straight forward as I expected it to be. For example you can't make the control widget a Functional Component, that's when you'll end up with this error: netlify-cms-app.js:247 Uncaught TypeError: this.wrappedControlValid is not a function.

How it actually does work is like this.

import React from 'react';
import CMS from 'netlify-cms-app';
import Immutable, { Map, List } from 'immutable';

type SelectOptions = List<{ label: string; value: string | number }>;
type ControlProps = {
    field: Map<string, string | SelectOptions>;
}

export class Control extends React.Component<ControlProps> {
    render() {
        const SelectControl = CMS.getWidget('select').control;
        const selectProps = { ...this.props };

        selectProps.field = selectProps.field.set('options',
            Immutable.List([
                { label: 'Hello', value: 1 },
                { label: 'Goodbye', value: 2 }
            ])
        );

        return (
            <SelectControl {...selectProps} />
        );
    }
}

Be aware that you need to modify the props of the component, to do that, I made a copy of the original props and called it selectProps. This way the original props don't get mutated.

Next up we need to change the options within the props.field. This is a Map from the immutable library. It returns the adjusted value, so we need to set selectProps.field with the new value. Next up we need to change the options list, that's a List from the immutable library. See above how you can change it.

You can imagine it's now easy to set it with any value you want. You can fetch new values from an API or set them as static values in Javascript.

The widget preview I haven't worked out completely, but a really basic implementation looks like this:

export const preview = (props) => {
    return (
        <div>{props.value}</div>
    );
}

That being said, I added these 2 lines of code to /src/cms/cms.tsx:

import { Control as customSelectorControl, Preview as customSelectorPreview } from './widgets/CustomSelector';

CMS.registerWidget('customSelector', customSelectorControl, customSelectorPreview);

And now you can use it like this in your static/admin/config.yml file:

- label: Custom selector
  name: customFields
  widget: customSelector

And that gives you a custom select component in the Netlify CMS with dynamic values.