To contribute, you might follow these steps:
- Comment on the GitHub Issue you want to work on or open a new one
- Fork the repo
- Start the development setup using docker-compose.yaml and by running
docker compose up - Depending on the ticket, you might also consider other guidelines below.
- Before opening a PR, make sure to run npm run build and confirm it runs without errors during build (can be run locally or inside a container, linting is disabled)
- Open a PR, which may include the following:
- reference an issue
- short description
- screenshots if UI changes
To add a new widget, follow these steps:
-
Register the widget
- Add an entry to
/public/widgets.jsonunder the correct category.- If the widget depends on external services (integration), prefix the category with
int:.
- If the widget depends on external services (integration), prefix the category with
- Example format:
{ "slug": "weather-overview", "name": "Quick overview", "description": "", "exampleProps": { "locationDisplayname": "Munich", "locationCoordinates": "48.1337, 11.5720", "unit": "c", "showLocation": false }, "properties": { "locationDisplayname": "as:string", "locationCoordinates": "as:string", "unit": "f|c", "showLocation": "as:bool" } }examplePropsis used for previewing the widget.
- Add an entry to
-
Add switch-case entry
- Update
components/widgets/Widget.tsxto load your widget dynamically viaimport(...). - Add a new case to
switch (type)pointing to your new component.
- Update
-
Create a widget component
- Place the component in:
components/widgets/dashboard/ - Components must accept:
export type WidgetItemProps = { className?: string; params?: Record<string, any>; };
- Place the component in:
-
(Optional) Implement an API client
- If your widget requires calls to external services:
- Create a client in:
lib/clients/<name>/client.ts - Example pattern (Karakeep):
export async function getBookmarks({ serverUrl, token }) { // fetch logic }
- Keep the client focused: input → fetch → normalized output.
- Create a client in:
- If your widget requires calls to external services:
Thank you for contributing and helping improve dashwise!