Add Widget for Vibe landing.repowidget.register
Choose a tool for developing with an AI agent:
- use Alaio Vibecode to build an app for Bitrix24 from a task description without knowing any programming language. The agent writes the code and deploys the app to a server, with no manual hosting setup
- use the MCP server to develop a REST API integration in your own project. The agent refers to the official REST documentation
Scope:
landingWho can execute the method: any user when called from an application; an administrator when called via a webhook
The method landing.repowidget.register adds a widget for the Vibe.
If the application has already registered a widget with this code, the method updates its content. Instances placed on Vibe pages are updated automatically.
Register the widget from an application: the handler of a widget registered via a webhook is not called. For details, see the overview of methods.
Method Parameters
Required parameters are marked with *
|
Name |
Description |
|
code* |
Widget code, unique within the application. Widgets of different applications with the same code do not conflict |
|
fields* |
Field values for creating the widget (detailed description) |
Parameter fields
Required parameters are marked with *
|
Name |
Description |
|
NAME* |
Widget name |
|
PREVIEW* |
URL of the widget cover image for the widget selection slider |
|
DESCRIPTION |
Widget description |
|
CONTENT* |
Widget markup using Vue constructs |
|
SECTIONS* |
Code of the section where the widget will be added. List of available sections:
|
|
WIDGET_PARAMS* |
Parameters for the Vue template engine |
|
ACTIVE |
Widget activity. Accepts values:
Default: |
|
SITE_TEMPLATE_ID |
Binding the widget to a specific site template. Only for on-premise Bitrix24! |
Parameter WIDGET_PARAMS
Required parameters are marked with *
|
Name |
Description |
|
rootNode* |
Selector for the root element in the |
|
lang |
Language phrases for The widget uses the phrases for the user's interface language; if there are none, it uses |
|
handler* |
Address of the external handler to which requests will be sent. Address requirements:
If the address does not meet the requirements, the method returns the |
|
style |
Address of styles for the widget. Styles can also be set inline in the markup via the binding |
|
demoData* |
Demo data for the widget. It is displayed in the Vibe template preview slider in the Market, so its structure must match the response of the If the widget will not be published in the Market, pass any object |
Code Examples
How to Use Examples in Documentation
// This snippet is an ES module: top-level await requires type="module" or a bundler.
// $b24 is an already-initialized SDK instance (see the SDK "Get started" guide).
import { Text } from '@bitrix24/b24jssdk'
import type { B24Frame } from '@bitrix24/b24jssdk'
declare const $b24: B24Frame
const content = '<div class="my-app-w-container"><!-- Vue template --></div>'
try {
const response = await $b24.actions.v2.call.make<number>({
method: 'landing.repowidget.register',
params: {
code: 'my_widget',
fields: {
NAME: 'My widget',
PREVIEW: 'https://my-app.com/vibe_preview.jpg',
CONTENT: content,
SECTIONS: 'widgets_company_life',
WIDGET_PARAMS: {
rootNode: '.my-app-w-container',
lang: {
ru: {
W_TITLE: 'People and their ages',
W_EMPTY: 'No data',
},
en: {
W_TITLE: 'People and their ages',
W_EMPTY: 'Empty',
},
},
handler: 'https://my-app.com/vibe.php',
style: 'https://my-app.com/vibe.css',
demoData: {
desc: 'Just a test widget',
count: 420,
persons: [
{ name: 'Person 1', age: 21 },
{ name: 'Person 2', age: 42 },
{ name: 'Person 3', age: 123 },
],
},
},
},
},
requestId: Text.getUuidRfc4122()
})
// The payload is available only on a successful response
if (!response.isSuccess) {
console.error(response.getErrorMessages().join('; '))
} else {
const result = response.getData()!.result
console.info('Registered widget ID:', result)
}
} catch (error) {
// Thrown on transport or SDK failures (AjaxError, SdkError, etc.)
console.error(error)
}
<!-- Load the SDK (UMD build); it is exposed as the global B24Js -->
<script src="https://unpkg.com/@bitrix24/b24jssdk@1/dist/umd/index.min.js"></script>
<script>
async function registerVibeWidget() {
try {
// Initialize the SDK inside a Bitrix24 frame
const $b24 = await B24Js.initializeB24Frame()
const content = '<div class="my-app-w-container"><!-- Vue template --></div>'
const response = await $b24.actions.v2.call.make({
method: 'landing.repowidget.register',
params: {
code: 'my_widget',
fields: {
NAME: 'My widget',
PREVIEW: 'https://my-app.com/vibe_preview.jpg',
CONTENT: content,
SECTIONS: 'widgets_company_life',
WIDGET_PARAMS: {
rootNode: '.my-app-w-container',
lang: {
ru: {
W_TITLE: 'People and their ages',
W_EMPTY: 'No data',
},
en: {
W_TITLE: 'People and their ages',
W_EMPTY: 'Empty',
},
},
handler: 'https://my-app.com/vibe.php',
style: 'https://my-app.com/vibe.css',
demoData: {
desc: 'Just a test widget',
count: 420,
persons: [
{ name: 'Person 1', age: 21 },
{ name: 'Person 2', age: 42 },
{ name: 'Person 3', age: 123 },
],
},
},
},
},
requestId: B24Js.Text.getUuidRfc4122()
})
// The payload is available only on a successful response
if (!response.isSuccess) {
console.error(response.getErrorMessages().join('; '))
return
}
const result = response.getData().result
console.info('Registered widget ID:', result)
} catch (error) {
// Thrown on transport or SDK failures (AjaxError, SdkError, etc.)
console.error(error)
}
}
document.addEventListener('DOMContentLoaded', registerVibeWidget)
</script>
from b24pysdk.errors import BitrixAPIError, BitrixSDKException
content = '<div class="my-app-w-container"><!-- Vue template --></div>'
try:
bitrix_response = client.landing.repowidget.register(
code="my_widget",
fields={
"NAME": "My widget",
"PREVIEW": "https://my-app.com/vibe_preview.jpg",
"CONTENT": content,
"SECTIONS": "widgets_company_life",
"WIDGET_PARAMS": {
"rootNode": ".my-app-w-container",
"lang": {
"ru": {
"W_TITLE": "People and their ages",
"W_EMPTY": "No data",
},
"en": {
"W_TITLE": "People and their ages",
"W_EMPTY": "Empty",
},
},
"handler": "https://my-app.com/vibe.php",
"style": "https://my-app.com/vibe.css",
"demoData": {
"desc": "Some people...",
"persons": [
{
"name": "Person 1",
"age": 21,
},
{
"name": "Person 2",
"age": 42,
},
{
"name": "Person 3",
"age": 123,
},
],
},
},
},
).response
result = bitrix_response.result
print(result)
except BitrixAPIError as error:
print(
"Bitrix API error",
f"error: {error.error}",
f"error_description: {error.error_description}",
sep="\n",
)
except BitrixSDKException as error:
print(f"Bitrix SDK error: {error.message}")
except Exception as error:
print(f"Unexpected error: {error}")
try {
$response = $b24Service
->core
->call(
'landing.repowidget.register',
[
'code' => 'my_widget',
'fields' => [
'NAME' => 'My widget',
'PREVIEW' => 'https://my-app.com/main_preview.jpg',
'CONTENT' => $content,
'SECTIONS' => 'widgets_company_life',
'WIDGET_PARAMS' => [
'rootNode' => '.my-app-w-container',
'lang' => [
'de' => [
'W_TITLE' => 'People and their ages',
'W_EMPTY' => 'Empty',
],
'en' => [
'W_TITLE' => 'People and their ages',
'W_EMPTY' => 'Empty',
},
],
'handler' => 'https://my-app.com/vibe.php',
'style' => 'https://my-app.com/vibe.css',
'demoData' => [
'desc' => 'Just a test widget',
'count' => 420,
'persons' => [
['name' => 'Person 1', 'age' => 21],
['name' => 'Person 2', 'age' => 42],
['name' => 'Person 3', 'age' => 123],
],
],
],
],
]
);
$result = $response
->getResponseData()
->getResult();
echo 'Success: ' . print_r($result, true);
// Your required data processing logic
processData($result);
} catch (Throwable $e) {
error_log($e->getMessage());
echo 'Error registering repowidget: ' . $e->getMessage();
}
const content = `
<div class="my-app-w-container">
<h2 class="w-title" :style="{borderBottom: '1px solid red'}">
{{$Bitrix.Loc.getMessage('W_TITLE')}}
</h2>
<h3>Description: {{desc}}</h3>
<div v-for="(value) in persons">
<p>
<span class="w-name">{{value.name}}</span>:
<span class="w-age">{{value.age}}</span>
</p>
</div>
<div v-if="persons == null">
{{$Bitrix.Loc.getMessage('W_EMPTY')}}
</div>
<h4>Just a number {{count}}</h4>
<div class="w-buttons">
<button @click="fetch">Get data (without parameters)</button>
<button @click="fetch({param: 'a'})">Data for parameter 'a'</button>
<button @click="fetch({param: 'b'})">Data for parameter 'b'</button>
<button @click="openApplication({param1: '1', param2: 'false'})">Open application</button>
<button @click="openPath('/crm')">Open local address in slider</button>
</div>
</div>
`;
const data = {
code: 'my_widget',
fields: {
NAME: 'My widget',
PREVIEW: 'https://my-app.com/main_preview.jpg',
CONTENT: content,
SECTIONS: 'widgets_company_life',
WIDGET_PARAMS: {
rootNode: '.my-app-w-container',
lang: {
de: {
W_TITLE: 'People and their ages',
W_EMPTY: 'Empty',
},
en: {
W_TITLE: 'People and their ages',
W_EMPTY: 'Empty',
},
},
handler: 'https://my-app.com/vibe.php',
style: 'https://my-app.com/vibe.css',
demoData: {
desc: 'Just a test widget',
count: 420,
persons: [
{'name': 'Person 1', 'age': 21},
{'name': 'Person 2', 'age': 42},
{'name': 'Person 3', 'age': 123},
],
},
},
},
};
BX24.callMethod(
'landing.repowidget.register',
data,
(result) =>
{
if (result.error())
{
console.error(result.error());
return;
}
console.info(result.data());
},
);
require_once('crest.php');
$content = <<<'HTML'
<div class="my-app-w-container">
<h2 class="w-title" :style="{borderBottom: '1px solid red'}">
{{$Bitrix.Loc.getMessage('W_TITLE')}}
</h2>
<h3>Description: {{desc}}</h3>
<div v-for="(value) in persons">
<p>
<span class="w-name">{{value.name}}</span>:
<span class="w-age">{{value.age}}</span>
</p>
</div>
<div v-if="persons == null">
{{$Bitrix.Loc.getMessage('W_EMPTY')}}
</div>
<h4>Just a number {{count}}</h4>
<div class="w-buttons">
<button @click="fetch">Get data (without parameters)</button>
<button @click="fetch({param: 'a'})">Data for parameter 'a'</button>
<button @click="fetch({param: 'b'})">Data for parameter 'b'</button>
<button @click="openApplication({param1: '1', param2: 'false'})">Open application</button>
<button @click="openPath('/crm')">Open local address in slider</button>
</div>
</div>
HTML;
$data = [
'code' => 'my_widget',
'fields' => [
'NAME' => 'My widget',
'PREVIEW' => 'https://my-app.com/main_preview.jpg',
'CONTENT' => $content, // Vue markup extracted into a separate variable for convenience
'SECTIONS' => 'widgets_company_life',
'WIDGET_PARAMS' => [
'rootNode' => '.my-app-w-container',
'lang' => [
'de' => [
'W_TITLE' => 'People and their ages',
'W_EMPTY' => 'Empty!',
],
'en' => [
'W_TITLE' => 'People and their ages',
'W_EMPTY' => 'Empty!',
],
],
'handler' => 'https://my-app.com/vibe.php',
'style' => 'https://my-app.com/vibe.css',
'demoData' => [
'desc' => 'Just a test widget',
'count' => 420,
'persons' => [
[
'name' => 'Person 1',
'age' => 21,
],
[
'name' => 'Person 2',
'age' => 42,
],
[
'name' => 'Person 3',
'age' => 123,
],
],
],
],
],
];
$result = CRest::call(
'landing.repowidget.register',
$data
);
echo '<PRE>';
print_r($result);
echo '</PRE>';
Response Handling
HTTP status: 200
{
"result": 10,
"time": {
"start": 1713949410.036288,
"finish": 1713949411.632775,
"duration": 1.596487045288086,
"processing": 0.6458539962768555,
"date_start": "2024-04-24T11:03:30+02:00",
"date_finish": "2024-04-24T11:03:31+02:00",
"operating": 0
}
}
Returned Data
|
Name |
Description |
|
result |
Identifier of the added widget |
|
time |
Information about the request execution time |
Error Handling
HTTP status: 400
{
"error":"REQUIRED_FIELD_NO_EXISTS",
"error_description":"The required field is missing: CONTENT"
}
|
Name |
Description |
|
error |
String error code. It consists of digits, Latin letters, and underscores. It may arrive empty — in that case only |
|
error_description |
Error message for the developer. Do not show it to the end user without processing |
Possible Error Codes
|
Status |
Code |
Description |
Value |
|
|
|
The required field is missing: CONTENT |
A required field is not passed in the |
|
|
|
The required widget parameter is missing: handler |
A required parameter is not passed in the |
|
|
|
Invalid handler URL in parameter WIDGET_PARAMS.handler |
The |
|
|
|
The contents of the block were marked as unsafe |
The |
|
|
|
— |
The method was called via a webhook by a user who is not an administrator |
|
|
|
Some of the call parameters were missing: fields |
The |
|
|
|
Invalid type of the call argument: fields |
The |
Statuses and System Error Codes
HTTP Status: 4xx, 5xx
The errors described below are returned by the REST API itself, not by the logic of a specific method. They can arrive in response to any method.
|
Status |
Code |
Description |
|
|
|
An internal server error has occurred. Retry the call, and if the error persists, contact the server administrator or Bitrix24 technical support |
|
|
|
The server returned an unexpected response. Retry the call, and if the error persists, contact the server administrator or Bitrix24 technical support |
|
|
|
The request intensity limit has been exceeded |
|
|
|
The method is blocked because the request resource intensity limit has been exceeded. The block is lifted automatically once the accumulated execution time of the method no longer exceeds the limit |
|
|
|
The request contains no authorization data: neither an access token nor a webhook code was passed |
|
|
|
Methods are called over the HTTPS protocol only |
|
|
|
The REST API is blocked due to overload. This is a manual individual block. To have it lifted, contact Bitrix24 technical support |
|
|
|
REST API access is not active for this account. In Bitrix24 Cloud, check the current plan or trial status: Vibe+ plans include REST API access, while Essentials plans do not. A webhook receives a different error message — |
|
|
|
No active webhook with the specified user identifier and secret code was found |
|
|
|
No method with this name was found. The name is misspelled, the method does not exist in the REST API, or it is unavailable without the required scope |
|
|
|
The request requires broader permissions than the token has: for a webhook these are the permissions granted to it, for an application it is the scope. For an application, the error message ends with |
|
|
|
The access token has expired |
|
|
|
The application is installed, but the Bitrix24 administrator has granted access to it only to specific users |
|
|
|
The public part of the site is closed. To open it on an on-premise installation, disable the "Temporary closure of the public part of the site" option. Path to the setting: Desktop > Settings > Product Settings > Module Settings > Main Module > Temporary closure of the public part of the site |