Widgets are defined as special types in your siteprofile, eg

types:
  widgets.coolblock:
    metaType: blockWidget
    editor:
      tabsExtension: /tolliumapps/widgets/widget.screens.xml#coolblock
    widgetBuilder: /js/widgets/builtin.ts#renderCoolBlockWidget
    members:
      data:
        type: string

metaType should be either blockWidget inlineWidget

Widgets can declare both a HareScript renderer and a TypeScript widgetBuilder - the APIs will then pick one based on context.

The renderer implementation:

import type { PagePartRequest } from "@webhare/router";
import type { TypedInstanceData } from "@webhare/whfs";
import { litty } from "@webhare/litty";

export async function renderJSWidget1(partReq: PagePartRequest, data: TypedInstanceData<"webhare_testsuite:base_test.jswidget1">) {
  return litty`<div>${data.field1}</div>`;
}

You can use apply rules to override widget settings for a specific location, eg

  - to:
      sitePath: /news/*
    comment: Override widget rendering in news section
    setWidget:
      widgets.coolblock:
        widgetBuilder: /js/widgets/builtin.ts#renderCoolBlockWidgetForNews