You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/MIDDLEWARE.md
+83Lines changed: 83 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,6 +2,13 @@
2
2
3
3
Middleware serves as a core element of Web Chat's architecture, enabling deep and cascaded UI customization.
4
4
5
+
Middleware operates in a cascading sequence, where the execution order plays a critical role. An upstream middleware can influence whether and how the downstream middleware renders. Middleware can perform the following operations:
6
+
7
+
- Add new UI
8
+
- Remove existing UI
9
+
- Replace existing UI
10
+
- Decorate existing UI
11
+
5
12
<!-- TODO: More docs -->
6
13
7
14
## Recipes
@@ -125,8 +132,57 @@ const polymiddleware = [
125
132
];
126
133
```
127
134
135
+
### Mixing polymiddleware with legacy middleware
136
+
137
+
> Notes: legacy middleware is deprecated and will be removed on or after 2027-08-16.
138
+
139
+
The following code snippet a legacy activity middleware followed by polymiddleware.
For a message activity of "Hello, World!", it will render:
158
+
159
+
```html
160
+
<divclass="legacy">
161
+
<divclass="polymiddleware">Hello, World!</div>
162
+
</div>
163
+
```
164
+
128
165
## Behaviors
129
166
167
+
### When will legacy middleware removed?
168
+
169
+
We started the polymiddleware in 2025-08-16. Based on our 2-year deprecation rule, legacy middleware will be removed on or after 2027-08-16. The following table should deprecation dates for various legacy middleware.
Polymiddleware is a unification of multiple legacy middleware into a single prop.
@@ -135,6 +191,33 @@ Previously, legacy middleware would sometimes return a render function and other
135
191
136
192
Polymiddleware enforces immutability of requests. Unlike legacy middleware, an upstreamer in polymiddleware is prohibited from passing a modified request to a downstreamer.
137
193
194
+
### Why we think polymiddleware is better?
195
+
196
+
We start using middleware (or chain of responsibility) pattern for UI customization since late 2018 when React hooks is still in its womb. Over the past 7.5 years, we learnt a lot.
197
+
198
+
- In other languages, middleware is called "chain of responsibility"
199
+
- Unique characteristics in Web Chat: bidirectional, synchronous, early termination
200
+
- Middleware overriding request offers flexibility but makes it very hard to debug
201
+
- Rendering become inconsistent when a buggy middleware is in the chain
202
+
- One middleware could change activity type and cause havoc
203
+
- Middleware should return render function than a React component
204
+
- Impossible to set a default prop (binding props) in React component without wasted rendering and various performance issues
205
+
- Hooks cannot be used in render function
206
+
- Render function and React component can be transformed to each other
207
+
- Ability to use hooks in middleware will reduce props and moving parts
208
+
- Build-time vs. render-time
209
+
- Request is build-time variable and primarily used to "decide whether middleware should add/remove/replace/decorate UI"
210
+
- Props and hooks are render-time variable and is for "how to render the UI"
211
+
- All UI-rendering middleware should share same API signature
212
+
- Card action and group activity middleware could be exempted because they are not UI-rendering
213
+
- Versioning API change is difficult
214
+
- Factory function can help backward and forward compatibility
215
+
- Props should be hide using React context as a wrapper
216
+
- Rendering flavor/variant should be part of the request but not a separate middleware
217
+
- "Attachment middleware for screen reader" could be avoided by adding a "for screen reader" flag in the request
218
+
- Everything should be a middleware, whether they are concrete (such as button and icon) or composed (such as send box)
219
+
- Error boundary should be the topmost middleware in the chain
220
+
138
221
### Polyfilling legacy middleware
139
222
140
223
Legacy middleware passed to deprecating props such as `activityMiddleware` will be polyfilled to polymiddleware after other polymiddleware passed via the `polymiddleware` prop.
0 commit comments