@tugitark/react-widget 1.4.1 → 1.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/from-scratch.md +86 -0
- package/index.md +7 -2
- package/package.json +39 -37
- package/using-library.md +18 -0
package/from-scratch.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
Reimplementing The Widget From Scratch
|
|
2
|
+
========================================
|
|
3
|
+
|
|
4
|
+
This library uses [@tugitark/declarative-widget](https://gitlab.com/tugitark/integration/libraries/javascript/declarative-widget) to handle the heavy lifting of detecting property changes, downloading the widget script, and (un)loading the actual widget tags on changes. Basically that library converts the imperative and static Tugi Tark chat widget in to a functional equivalent. All this library does is call that library from inside a component.
|
|
5
|
+
|
|
6
|
+
The code below demonstrates the basics of what is going on behind the scenes within that library. As detailed in [the original integration guide](https://www.tugitark.com/chat-setup), at some point the widget implementation must be imported using `<script>` and initialised via `window.tugiWidget.initialize()`. This example handles those operations by dynamically loading the script via javascript, then calling the API method once the loading is completed. The full version also handles unloading of the script for updates that cannot be applied after initialisation. However, unloading the widget was never an intended operation and so how it is done uses several internal details that should not be replicated in your code, and will not br replicated here.
|
|
7
|
+
|
|
8
|
+
Steps
|
|
9
|
+
=======
|
|
10
|
+
|
|
11
|
+
* *Load the script*
|
|
12
|
+
|
|
13
|
+
Create a `<script>` tag dynamically and inject it in to the page (if required):
|
|
14
|
+
|
|
15
|
+
```javascript
|
|
16
|
+
function loadScript() {
|
|
17
|
+
if (window.tugiWidget) {
|
|
18
|
+
// The script already exists.
|
|
19
|
+
initialise();
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const script = document.createElement('script');
|
|
23
|
+
// This attribute is recommended in the integration guide but may not work on `http` (testing).
|
|
24
|
+
//script.crossOrigin = 'anonymous';
|
|
25
|
+
script.async = true;
|
|
26
|
+
script.src = 'https://app.tugi.ai/tugi.widget/script';
|
|
27
|
+
script.onload = initialise;
|
|
28
|
+
script.onerror = (e) => console.error(e);
|
|
29
|
+
script.setAttribute('tugi-widget-script', 'true');
|
|
30
|
+
document.head.appendChild(script);
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
* *Initialise the widget*
|
|
35
|
+
|
|
36
|
+
The details here are partially supplied by Tugi Tark (e.g. the `brandId`), and otherwise customisable by you:
|
|
37
|
+
|
|
38
|
+
```javacript
|
|
39
|
+
function initialise() {
|
|
40
|
+
window.tugiWidget.initialize({
|
|
41
|
+
jwtFn: getUserToken,
|
|
42
|
+
tenantId: 'gb-casinos-ltd',
|
|
43
|
+
brandId: 'a040050697fc4b2db16acfbbad1d0da4',
|
|
44
|
+
brandName: 'Super Casino',
|
|
45
|
+
httpUrl: 'https://app.tugi.ai/tugi.widget',
|
|
46
|
+
wsUrl: 'wss://ws.tugi.ai',
|
|
47
|
+
customize: {
|
|
48
|
+
title: 'Super Casino Chat',
|
|
49
|
+
showTitle: true,
|
|
50
|
+
fontColor: PRIMARY_COLOUR,
|
|
51
|
+
primaryColor: PRIMARY_COLOUR,
|
|
52
|
+
secondaryColor: 'hsla(36, 100%, 50%, 1)',
|
|
53
|
+
homePageBackgroundColor: 'hsla(36, 100%, 37%, 0.2)',
|
|
54
|
+
homePageTextColor: PRIMARY_COLOUR,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
* *Request the JWT*
|
|
61
|
+
|
|
62
|
+
This requires a user that is logged in:
|
|
63
|
+
|
|
64
|
+
```javacript
|
|
65
|
+
async function getUserToken() {
|
|
66
|
+
const response = await fetch('/users/current/tugi-token');
|
|
67
|
+
if (response.ok) {
|
|
68
|
+
const jwt = await response.text();
|
|
69
|
+
if (jwt !== '') return jwt;
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Note that the standard endpoint for getting JWTs is `/.tugi/jwt/issue?id=<user-id>`. The default code will use this endpoint if no `jwtFn` is supplied.
|
|
76
|
+
|
|
77
|
+
* *Refesh the widget*
|
|
78
|
+
|
|
79
|
+
If a user logs in after loading the widget tell it so it can update the JWT:
|
|
80
|
+
|
|
81
|
+
```javacript
|
|
82
|
+
if (window.tugiWidget?.isInitialized()) {
|
|
83
|
+
window.tugiWidget.refresh();
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
package/index.md
CHANGED
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
|
|
4
4
|
This library wraps the Tugi Tark chat widget in a standardised react component. The component internally handles loading the latest version of the widget script from our CDN and translates between the imperative API controlling the widget and the react data flow model to configure things based purely on properties and callbacks.
|
|
5
5
|
|
|
6
|
+
Also see [the original integration guide](https://www.tugitark.com/chat-setup) for more information about the widget itself.
|
|
7
|
+
|
|
6
8
|
Minimal Example
|
|
7
9
|
-----------------
|
|
8
10
|
|
|
9
|
-
This is the smallest number of properties that you can pass to `<TugiWidget>` and have it still operate correctly.
|
|
11
|
+
This is the smallest number of properties that you can pass to `<TugiWidget>` and have it still operate correctly. These properties are given to you on signing up with Tugi Tark and must be entered accurately.
|
|
10
12
|
|
|
11
13
|
```javascript
|
|
12
14
|
import TugiWidget from '@tugitark/react-widget';
|
|
@@ -150,7 +152,6 @@ The following optional properties are shared with the full version:
|
|
|
150
152
|
|
|
151
153
|
While there can be only one widget on the page there can be multiple `<TugiWidget>` components at once. Which one will be used is non-deterministic - even if you have one `<TugiWidget>` with `visible={true}` and another one with `visible={false}` this will not guarantee that the visible one is the one that gets shown, the invisible one may be "shown", resulting in neither being seen. The one selected is based on internal render and update orders. Further, having two at once may result in the widget being constantly unloaded and reloaded even when nothing has changed as the underlying code flips repeatedly between them. If you have two versions of the widget shown in different circumstances then make sure that the whole component is conditional:
|
|
152
154
|
|
|
153
|
-
|
|
154
155
|
```javascript
|
|
155
156
|
return (
|
|
156
157
|
disabled
|
|
@@ -185,3 +186,7 @@ return (
|
|
|
185
186
|
);
|
|
186
187
|
```
|
|
187
188
|
|
|
189
|
+
[Click here](using-library.md) to see how this component wraps the underlying [@tugitark/declarative-widget](https://gitlab.com/tugitark/integration/libraries/javascript/declarative-widget) library in a react component.
|
|
190
|
+
|
|
191
|
+
[Click here](from-scratch.md) to get a better understanding of everything that that library is doing behind the scenes to inject the main widget script in to a page and initialise it.
|
|
192
|
+
|
package/package.json
CHANGED
|
@@ -1,37 +1,39 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@tugitark/react-widget",
|
|
3
|
-
"version": "1.4.
|
|
4
|
-
"description": "Wraps the tugitark widget in a React component.",
|
|
5
|
-
"scripts": {
|
|
6
|
-
"build": "npx esbuild index.ts --target=es6 --outfile=index.js && sed -i 's/\\bconst\\b/var/g' index.js && sed -i 's/\\blet\\b/var/g' index.js && npx esbuild index.js --allow-overwrite --minify --target=es5 --outfile=index.js && npx tsc --noErrorTruncation --declaration --emitDeclarationOnly --target es6 --module nodenext --moduleResolution nodenext --outDir . index.ts",
|
|
7
|
-
"release": "npm publish --access public",
|
|
8
|
-
"prerelease": "npm run build"
|
|
9
|
-
},
|
|
10
|
-
"files": [
|
|
11
|
-
"index.d.ts",
|
|
12
|
-
"index.js",
|
|
13
|
-
"index.md"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@tugitark/react-widget",
|
|
3
|
+
"version": "1.4.4",
|
|
4
|
+
"description": "Wraps the tugitark widget in a React component.",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"build": "npx esbuild index.ts --target=es6 --outfile=index.js && sed -i 's/\\bconst\\b/var/g' index.js && sed -i 's/\\blet\\b/var/g' index.js && npx esbuild index.js --allow-overwrite --minify --target=es5 --outfile=index.js && npx tsc --noErrorTruncation --declaration --emitDeclarationOnly --target es6 --module nodenext --moduleResolution nodenext --outDir . index.ts",
|
|
7
|
+
"release": "npm publish --access public",
|
|
8
|
+
"prerelease": "npm run build"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"index.d.ts",
|
|
12
|
+
"index.js",
|
|
13
|
+
"index.md",
|
|
14
|
+
"using-library.md",
|
|
15
|
+
"from-scratch.md"
|
|
16
|
+
],
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@tugitark/declarative-widget": "^1.2.3"
|
|
19
|
+
},
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"react": ">=0.0.0"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"esbuild": "^0.27.2",
|
|
25
|
+
"react": "^19.2.3",
|
|
26
|
+
"typescript": "^5.9.3"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"Typescript",
|
|
30
|
+
"React",
|
|
31
|
+
"Tugitark",
|
|
32
|
+
"Casino",
|
|
33
|
+
"Integration",
|
|
34
|
+
"JWT",
|
|
35
|
+
"Library"
|
|
36
|
+
],
|
|
37
|
+
"author": "alex.cole@tugitark.com",
|
|
38
|
+
"license": "(c) 2026 Tugi Tark OÜ"
|
|
39
|
+
}
|
package/using-library.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Reimplementing The Widget With A Library
|
|
2
|
+
==========================================
|
|
3
|
+
|
|
4
|
+
This library uses [@tugitark/declarative-widget](https://gitlab.com/tugitark/integration/libraries/javascript/declarative-widget) to handle the heavy lifting of detecting property changes, downloading the widget script, and (un)loading the actual widget tags on changes. Basically that library converts the imperative and static Tugi Tark chat widget in to a functional equivalent. All this library does is call that library from inside a component.
|
|
5
|
+
|
|
6
|
+
The code below, while unoptimised, demonstrates how this compoment wraps that library. See [the source code](index.ts) for more details.
|
|
7
|
+
|
|
8
|
+
```typescript
|
|
9
|
+
import render, { type Props } from '@tugitark/declarative-widget';
|
|
10
|
+
|
|
11
|
+
export default function TugiWidget(props: Props) {
|
|
12
|
+
render(props);
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The full version contains a few additional checks to ensure that certain events are only triggered once per component instance. But other than that, this is essentially all there is to this wrapper. All the complexities of reloading and updating the actual widget implementation itself are handled in the *declarative-widget* library itself. See [the from-scratch example](from-scratch.md) for a deeper explanation of what is happening behind the scenes in that library.
|
|
18
|
+
|