Settings and storage
Settings are what a person chooses. Storage is what your code keeps. Secrets are keys and tokens your server part needs.
Settings
Every extension has a page under Settings, Extensions. Describe fields and Ruimte draws them:
import { defineExtensionSettings } from '@ruimte/extension/client';
defineExtensionSettings({
fields: [
{
key: 'summaryLength',
type: 'select',
label: 'Summary length',
description: 'How long a summary of a canvas gets.',
default: 'short',
options: [
{ value: 'short', label: 'Short' },
{ value: 'long', label: 'Long' }
]
},
{
key: 'includeTerminals',
type: 'boolean',
label: 'Include terminals',
default: true
}
]
});A field is boolean (a switch), text (an input) or select (a menu with options). default is the value until the person changes it.
With more than a few fields, sort them into groups. Each group is a card with its title above it, as in Ruimte's own settings:
defineExtensionSettings({
groups: [
{
title: 'Summaries',
description: 'What Summarize writes.',
fields: [
{
key: 'summaryLength',
type: 'select',
label: 'Summary length',
default: 'short',
options: [
{ value: 'short', label: 'Short' },
{ value: 'long', label: 'Long' }
]
}
]
},
{
title: 'Sources',
fields: [
{
key: 'includeTerminals',
type: 'boolean',
label: 'Include terminals',
default: true
}
]
}
]
});A key is unique across all groups.
Read a setting in a component with useSetting. The component draws again when the person changes it.
import { useSetting } from '@ruimte/extension/client';
export default function Summary() {
const length = useSetting<string>('summaryLength');
return <p>{length === 'long' ? 'Long summary' : 'Short summary'}</p>;
}Settings live on the computer the person changed them on. The server part does not see them; pass what it needs as an argument when you call it.
For more than fields, draw the page yourself:
defineExtensionSettings({
component: () => import('./Settings'),
keywords: ['summary', 'length']
});keywords let the search in Settings find your page. Ruimte draws your component under the permissions, where the fields would go:
One call takes component, fields or groups, never two of them. With fields or groups beside it, Ruimte leaves component out and draws only the fields. For fields and a component of your own on one page, call defineExtensionSettings twice. Ruimte draws the fields first and your component below them.
Add a settings page builds both kinds of page.
Storage
useStorage keeps a value and draws again when it changes:
const [count, setCount] = useStorage('count', 0, 'project');The third argument says where the value lives:
| Scope | Where | Use it for |
|---|---|---|
computer (default) | This computer only | View preferences, what was last open |
project | The machine, per project | Data that belongs to a project, on every computer that opens it |
machine | The machine, for all projects | Data the server part also reads |
The server part reads and writes machine values with storage.get and storage.set.
A node keeps its own data with useNodeData, in the project itself. See Surfaces.
Secrets
secrets keeps strings, such as an API key, on the machine in a file only the person who runs it can read. Only the server part has it.
import { secrets } from '@ruimte/extension/server';
const token = await secrets.get('token');Ask for the value in a component of your settings page, and send it to the server part, which stores it with secrets.set.
Words
Put your words in locales/<language>.json, with en.json as the fallback:
{
"summarize": "Summarize",
"notes": "{{count}} notes"
}useLocale() gives t for words and format for numbers and dates, in the language and region the person chose:
const { t, format } = useLocale();
return <span>{t('notes', { count: 3 })}</span>;