This is a viewer only at the moment see the article on how this works.
To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk
This is a preview from the server running through my markdig pipeline
Monday, 01 June 2026
bot detection should not stop at allow
**
@stylobot/coreऔर@stylobot/nodenpm पैकेजों को शीघ्र प्रकाशित किया जाएगा** नीचे दिए गए अंशों में वह सतह का वर्णन किया गया है जो वे प्रदर्शित करेंगे
स्टिलियोबोट रिलेस शृंखला
- व्यवहार, पहचान नहीं: क्यों StyloBot ग्राहक व्यवहारिक रूप से मॉडल करता है
- व्यवहार-Aware ASP.NET UIसर्वर : NET अनुप्रयोगों के लिए प्रदान किया गया सतह
- लंबे समय तक चलाने वाले नेट सेवाओं में असीमित विकास का पता लगाना और स्थिर करना: विश्वसनीयता अनुशासन जो उत्पादन में इंजन को नीरस बनाए रखता है
- व्यवहार-Aware TypeScript UI: इस लेख
- साइडकार वास्तुकला: कैसे पता लगाने की इंजन गैर--.NET स्टाक से जुड़ता है
- तेजी से सीखनाअनुकूलन सीखने की प्रणाली
- उस चीज़ का परीक्षण जो सफल नहीं हो रही है: सत्यापन अनुशासन
- स्टिलियोएक्सट्रैक्ट - एक स्थानीय सीखने के HTML को मार्कडाउन रूपांतरक में: एचटीएमएल\→\मार्कडाउन परत जो डिटेक्टर के साथ जोड़ता है,\walker bug lucidVIEW पकड़ा\M SK3\ और कुत्तेfood लूप कि यह ईमानदार बना
स्टेलोबोट का पता लगाने वाला इंजन ASP में लिखा गया है। तेजी से सीखना: एक बार एक अंगुली छाप पर्याप्त विश्वास के साथ देखा गया है, , निर्णय कैश पूर्ण डिटेक्टर पाइपलाइन छोड़ता है और माइक्रोसेकेंड में उत्तर देता है
Most bot detection available in the TypeScript ecosystem gives you one of two things: a browser fingerprint that tells you whether the क्लाइंट स्वचालित दिखता है
अनुप्रयोग परत में उपयोगिता नहीं है
बोट ब्राउज़र में चलाता है और अनुरोध शीर्षिकाओं का कोई दृश्य नहीं रखताis-bot, isbot) पकड़ें केवल जो पकड़े जाने के लिए विकल्प करता है।
What StyloBot gives your TypeScript application is a verdict: a typed result with a continuous bot probability scoreAiBot, Scraper, GoodBot, MaliciousBotएक जोखिम पट्टी, एक सिफारिश की गई कार्रवाई, और एक खतरे स्कोर. क्या आप उस निर्णय के साथ करते हैं आप पर है
इस लेख में एक नमूना स्टोर फ्रंट के माध्यम से चलता है और दिखाता है कि कैसे यह निर्णय प्रत्येक परत पर अनुप्रयोग व्यवहार बन जाता है
अन्य किसी भी चीज़ से पहले यह है जो आता है
// @stylobot/core
interface Verdict {
isBot: boolean;
botProbability: number; // 0.0–1.0 - not binary, a continuous score
confidence: number; // certainty in that score
botType: BotType | null; // 'AiBot' | 'Scraper' | 'GoodBot' | 'MaliciousBot' | ...
botName: string | null; // 'GPTBot', 'Googlebot', 'curl/8.9.1', ...
riskBand: RiskBand; // 'VeryLow' | 'Low' | 'Elevated' | 'Medium' | 'High' | 'VeryHigh'
recommendedAction: RecommendedAction; // 'Allow' | 'Throttle' | 'Challenge' | 'Block'
threatScore: number; // elevated when CVE probes or credential stuffing detected
threatBand: ThreatBand; // 'None' | 'Low' | 'Elevated' | 'High' | 'Critical'
}
एक चेकआउट अंतबिंदु throttle कर सकता है Medium इसे रोकने के बजाय जोखिम AiBot दर से ट्रैफिक- वास्तविक उपयोगकर्ताओं के विरुद्ध यह गणना किए बिना सीमित कोटियाँ Elevated जोखिम के लिए अनुभव न छूते हुए Low जोखिम посетителей. यदि पता लगाने का परिणाम नेटवर्क परत पर एक बुलियन है तो इनमें से कोई भी संभव नहीं है
क्रम में जोखिम पट्टी VeryLow, Low, Elevated, Medium, High, VeryHigh, Verified.
npm install @stylobot/core @stylobot/node
# only needed for grpc mode
npm install @grpc/grpc-js @grpc/proto-loader
@stylobot/core रनटाइम निर्भरताओं को शून्य रखता है. इसमें प्रकार परिभाषाएं शामिल हैं, रेस्ट क्लाइंट, हेडर पार्सर\M SK3 और MSC4 वैकल्पिक रूप से) जीआरपीसी क्लाइन्ट\MST6 यह नोड में कार्य करता है\MSC7 डेनो\MSP8\ तथा बिना परिमार्जन के बान में काम करता है
@stylobot/node एक्सप्रैस मिडवेअर प्रदान करता है, एक फस्टीफ़िफाई प्लगइन, टेम्प्लेट मददगार उपयोगिताएंMSC2 और निर्णायक इंजेक्टरM SK3 यह पर निर्भर करता है @stylobot/core और रनटाइम पर कुछ भी नहीं
मिडलवेयर में तीन मोड हैं req.stylobot आकार. जिसको आप उपयोग करते हैं यह निर्भर करता है कि आपके अवसंरचना पता लगाने में कहाँ चलता है
graph LR
classDef input fill:none,stroke:#3b82f6,stroke-width:2px
classDef good fill:none,stroke:#22c55e,stroke-width:2px
classDef async fill:none,stroke:#a855f7,stroke-width:2px
subgraph H ["headers mode - zero added latency"]
GW[Gateway / Caddy / YARP]:::input -->|"X-StyloBot-* headers"| A[Express / Fastify]:::good
end
subgraph G ["grpc mode - HTTP/2, no JSON overhead"]
B[Express / Fastify]:::good -->|"gRPC Detect RPC"| SC[StyloBot Sidecar :5090]:::async
end
subgraph R ["api mode - REST, full signal set"]
C[Express / Fastify]:::good -->|"POST /api/v1/detect"| SC2[StyloBot Sidecar :5091]:::async
end
headers मोडपता गेटवे पर ऊपरी धारा में चला गया।
grpc मोड: मेडवेअर HTTP के माध्यम से सीधा sidecar को कॉल करता है @grpc/grpc-js. जीआरपीसी अंतरफलक और साइडकार विन्यास विवरण में हैं साइडकार वास्तुकला लेख.
api मोड: कॉल्स POST /api/v1/detect HTTP के ऊपर /1.1. भी लौटता है reasons (perM SK1detector contributions) और signals पूर्ण ब्लैकबोर्ड स्थिति
मिडलवेयर हमेशा खोलने में विफल होता है req.stylobot एक अनुमतिपूर्ण खाली निर्णय पर सेट किया जाता है और अनुरोध जारी रहता है.
एक्सप्रेस
import express from 'express';
import { styloBotMiddleware } from '@stylobot/node';
const app = express();
app.use(styloBotMiddleware({ mode: 'headers' }));
// or:
app.use(styloBotMiddleware({ mode: 'grpc', endpoint: 'localhost:5090', timeout: 100 }));
त्वरित करें
import Fastify from 'fastify';
import { styloBotPlugin } from '@stylobot/node';
const fastify = Fastify();
await fastify.register(styloBotPlugin, { mode: 'headers' });
@info: whatsthis
// types.d.ts
import type { StyloBotResult } from '@stylobot/node';
declare module 'fastify' {
interface FastifyRequest { stylobot: StyloBotResult; }
}
एक ही नमूना स्टोरफ़ॉन्ट से ASP.NET अनुच्छेदउत्पाद पृष्ठ, checkout, login, newsletter, लेकिन टाइपस्क्रिप्ट में. detection result is the same; what changes is how the surface exposes it
मूल्य scrapers यहाँ से आरंभ होते हैं।
परिदृश्य-:-एक मूल्य scraper Hits /products/:idयह कोई डिस्काउंट कोड नहीं देखता।
रूट हैंडलर
app.get('/products/:id', (req, res) => {
const { verdict } = req.stylobot;
const product = getProduct(req.params.id);
res.render('product', {
product,
sbVerdict: verdict,
showDiscount: verdict.riskBand === 'VeryLow' || verdict.riskBand === 'Low',
showBuyButton: !verdict.isBot,
showCartWarning: verdict.recommendedAction === 'Challenge',
isSearchBot: verdict.botType === 'SearchEngine' || verdict.botType === 'VerifiedBot',
});
});
टेम्पलेट (Handlebars):
{{! verified crawlers get structured metadata instead of commercial UI }}
{{#if isSearchBot}}
<meta name="description" content="{{product.name}} -{{product.category}}." />
<p>{{product.description}}</p>
{{else}}
{{! discount only for low-risk human visitors }}
{{#if showDiscount}}
<div class="alert alert-success">
Member price: use code <strong>LOYAL10</strong> for 10% off.
</div>
{{/if}}
{{! add-to-cart only for non-bot traffic }}
{{#if showBuyButton}}
<form method="post" action="/cart/add">
<input type="hidden" name="productId" value="{{product.id}}" />
{{#if showCartWarning}}
<p class="text-warning">Additional verification may be required at checkout.</p>
{{/if}}
<button type="submit" class="btn btn-primary">Add to Cart</button>
</form>
{{else}}
<p class="text-muted">Purchase available to human visitors.</p>
{{/if}}
{{/if}}
यहाँ उपयोग में तीन नमूने SearchEngine और VerifiedBot बिना वाणिज्यिक संकेतों के संरचनात्मक मेटाडेटा प्राप्त करें। Challenge एक चेतावनी है
धोखाधड़ी स्वचालन, कार्ड परीक्षकों, वाउचर ब्रूटMSC2 फोर्सरM SK3 और स्क्रिप्ट रिट्रीएं सभी चेकआउट पर एकजुट होते हैं . लक्ष्य एक CAPTCHA के बिना गहराई में बचाव है
परिदृश्य: एक वाउचर-testing bot hits /checkoutयह एक मरे हुए को देखता है।
flowchart TD
classDef input fill:none,stroke:#3b82f6,stroke-width:2px
classDef good fill:none,stroke:#22c55e,stroke-width:2px
classDef problem fill:none,stroke:#ef4444,stroke-width:2px
A([Visitor reaches /checkout]):::input --> B{bot?}
B -->|yes| C[Dead-end message - no form]:::problem
B -->|no| D{risk band}
D -->|Low| E[Express checkout CTA]:::good
D -->|Elevated| F[Standard checkout CTA]:::good
D -->|High+| G[Phone number - no online path]:::problem
E & F --> H[POST /checkout/order]
H --> I{honeypot triggered?}
I -->|yes| J[Silent fake confirmation]:::problem
I -->|no| K[Process real order]:::good
मार्ग
app.get('/checkout', (req, res) => {
const { verdict } = req.stylobot;
res.render('checkout', {
sbVerdict: verdict,
showForm: !verdict.isBot,
showExpress: verdict.riskBand === 'VeryLow' || verdict.riskBand === 'Low',
showStandard: ['VeryLow','Low','Elevated'].includes(verdict.riskBand),
showPhone: ['High','VeryHigh'].includes(verdict.riskBand),
});
});
app.post('/checkout/order', (req, res) => {
// honeypot fields are invisible to humans; bots fill everything
if (req.body.hp_name || req.body.hp_email) {
return res.redirect('/checkout/confirmed'); // silent fake - no retry incentive
}
return processRealOrder(req, res);
});
टेम्प्लेट
{{#if showForm}}
<form method="post" action="/checkout/order">
{{! invisible honeypot trap - humans leave blank, bots fill everything }}
<div style="position:absolute;left:-9999px;opacity:0" aria-hidden="true">
<input type="text" name="hp_name" tabindex="-1" autocomplete="off" />
<input type="email" name="hp_email" tabindex="-1" autocomplete="off" />
</div>
{{#if showExpress}}
<button type="submit" name="express" value="true" class="btn btn-success btn-lg">
Express Checkout
</button>
{{/if}}
{{#if showStandard}}
<button type="submit" class="btn btn-primary">Proceed to Payment</button>
{{/if}}
{{#if showPhone}}
<p>Please call us to complete your order: <strong>0800 123 456</strong></p>
{{/if}}
</form>
{{else}}
<p class="text-muted">Checkout is available to human visitors only.</p>
{{/if}}
Honeypot discard यहाँ कुंजी तकनीक है. त्रुटि फीडबैक हमलावरों को दोहराने के लिए सिखाता है। <div> साझा हैंडलबार आंशिक में wrapper ({{> honeypot}}प्रतिरक्षित प्रत्येक फार्म पर इनलाइन शैली ब्लॉक को दोहराने के बजाय )
लॉगिन विश्वसनीय है।
Scenario: a credential-stuffing script hits /login. यह एक हतोत्साहित संदेश को देखता है /login/denied किसी भी प्रमाणीकरण चलाने से पहले
app.get('/login', (req, res) => {
const { verdict } = req.stylobot;
res.render('login', {
sbVerdict: verdict,
showWarning: verdict.isBot,
showRisk: ['High','VeryHigh'].includes(verdict.riskBand),
});
});
app.post('/login', async (req, res) => {
if (req.body.hp_user || req.body.hp_pass) {
return res.redirect('/login/denied');
}
if (req.stylobot.verdict.isBot) {
return res.redirect('/login/denied');
}
return authenticate(req, res);
});
{{#if showRisk}}
<div class="alert alert-danger">
High-risk signals detected. Login attempts are logged.
</div>
{{/if}}
{{#if showWarning}}
<div class="alert alert-warning">
Automated login attempts are detected and blocked.
</div>
{{/if}}
<form method="post" action="/login">
<div style="position:absolute;left:-9999px;opacity:0" aria-hidden="true">
<input type="text" name="hp_user" tabindex="-1" autocomplete="off" />
<input type="password" name="hp_pass" tabindex="-1" autocomplete="off" />
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" id="email" name="email" autocomplete="email" />
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" name="password" autocomplete="current-password" />
</div>
<button type="submit" class="btn btn-primary">Sign In</button>
</form>
बॉट प्रस्तुत करने से पहले हतोत्साहित को देखता है verdict.isBot कोई भी प्रमाणीकरण तर्क चलाने से पहले अंतिम सर्वर है
अभियांत्रिक क्रैलेटर एक भिन्न समस्या हैं।
परिदृश्य: जीपीटीबीओट Hits /newsletterयह सदस्यता पैच के बजाय डेटा लाइसेंस संदेश देखता है
app.get('/newsletter', (req, res) => {
const { verdict } = req.stylobot;
res.render('newsletter', {
sbVerdict: verdict,
isHuman: !verdict.isBot,
isAiBot: verdict.botType === 'AiBot',
isOtherBot: verdict.isBot && verdict.botType !== 'AiBot',
});
});
app.post('/newsletter/subscribe', (req, res) => {
if (req.body.hp_email2 || req.stylobot.verdict.isBot) {
return res.redirect('/newsletter/thanks'); // silent discard
}
mailingList.subscribe(req.body.email);
return res.redirect('/newsletter/thanks');
});
{{#if isHuman}}
<p>Get exclusive deals delivered to your inbox. Unsubscribe any time.</p>
{{/if}}
{{#if isAiBot}}
<div class="alert alert-info">
This subscription endpoint is for human readers.
For data licensing enquiries, <a href="/contact">contact us directly</a>.
</div>
{{/if}}
{{#if isOtherBot}}
<div class="alert alert-warning">
Automated subscription attempts are discarded.
</div>
{{/if}}
<form method="post" action="/newsletter/subscribe">
<div style="position:absolute;left:-9999px;opacity:0" aria-hidden="true">
<input type="email" name="hp_email2" tabindex="-1" autocomplete="off" />
</div>
<div class="form-group">
<input type="email" name="email" placeholder="[email protected]" autocomplete="email" />
</div>
<button type="submit" class="btn btn-success">Subscribe</button>
</form>
AiBot यह एक वर्गीकरण है जो व्यापार प्रतिक्रिया सक्षम करता है।
sbVerdictInjector खोज मिडवेअर के बाद चलाता है और निर्णय पर रखता है res.locals:
import { sbVerdictInjector } from '@stylobot/node';
app.use(styloBotMiddleware({ mode: 'headers' }));
app.use(sbVerdictInjector({ mode: 'gateway' }));
// or for direct sidecar calls (REST port, not the gRPC port):
app.use(sbVerdictInjector({ mode: 'sidecar', endpoint: 'http://localhost:5091' }));
res.locals.sbVerdict प्रत्येक टेम्प्लेट में उपलब्ध है res.locals.sbVerdictScript एक इनलाइन है <script> टैग जो सेट करता है window.__sb ब्राउज़र घटकों के लिए
परिभाषित करें RISK_ORDER एक बार मॉड्यूल क्षेत्र में (Nunjucks और EJS सहायक नीचे उसी नक्शे का उपयोग करें
import type { Verdict, RiskBand } from '@stylobot/core';
const RISK_ORDER: Record<string, number> = {
Unknown: 0, VeryLow: 1, Low: 2, Elevated: 3, Medium: 4, High: 5, VeryHigh: 6, Verified: 7,
};
// register on your Handlebars engine instance
hbs.engine({
helpers: {
// {{#sbGate sbVerdict "Low"}}...{{else}}...{{/sbGate}}
sbGate(verdict: Verdict | null, maxRisk: string, options: any) {
if (!verdict) return options.fn(this);
return RISK_ORDER[verdict.riskBand] <= RISK_ORDER[maxRisk]
? options.fn(this)
: options.inverse(this);
},
// {{#sbIsBot sbVerdict}}...{{else}}...{{/sbIsBot}}
sbIsBot(verdict: Verdict | null, options: any) {
return verdict?.isBot ? options.fn(this) : options.inverse(this);
},
// {{#sbBotType sbVerdict "AiBot"}}...{{/sbBotType}}
sbBotType(verdict: Verdict | null, type: string, options: any) {
return verdict?.botType === type ? options.fn(this) : options.inverse(this);
},
// {{#sbMinRisk sbVerdict "High"}}...{{/sbMinRisk}}
sbMinRisk(verdict: Verdict | null, minRisk: string, options: any) {
if (!verdict) return options.inverse(this);
return RISK_ORDER[verdict.riskBand] >= RISK_ORDER[minRisk]
? options.fn(this)
: options.inverse(this);
},
},
});
टेम्प्लेट में
{{#sbGate sbVerdict "Low"}}
<a href="/checkout/express" class="btn btn-success">Express Checkout</a>
{{else}}
<a href="/checkout" class="btn btn-secondary">Checkout</a>
{{/sbGate}}
{{#sbBotType sbVerdict "AiBot"}}
<div class="alert alert-info">AI crawler detected. Data licensing info above.</div>
{{/sbBotType}}
{{#sbMinRisk sbVerdict "High"}}
<div class="alert alert-danger">High-risk session. Some features restricted.</div>
{{/sbMinRisk}}
import nunjucks from 'nunjucks';
// RISK_ORDER - same map defined in the Handlebars section above
class SbGateExtension {
tags = ['sbgate'];
parse(parser: any, nodes: any, lexer: any) {
const tok = parser.nextToken();
const args = parser.parseSignature(null, true);
parser.advanceAfterBlockEnd(tok.value);
const body = parser.parseUntilBlocks('else', 'endsbgate');
let elseBody = null;
if (parser.skipSymbol('else')) {
parser.skip(lexer.TOKEN_BLOCK_END);
elseBody = parser.parseUntilBlocks('endsbgate');
}
parser.advanceAfterBlockEnd();
return new nodes.CallExtension(this, 'run', args, [body, elseBody]);
}
run(context: any, maxRisk: string, body: any, elseBody: any) {
const v = context.ctx.sbVerdict;
const fits = !v || RISK_ORDER[v.riskBand] <= RISK_ORDER[maxRisk];
return fits ? body() : (elseBody?.() ?? '');
}
}
env.addExtension('SbGateExtension', new SbGateExtension());
{% sbgate "Low" %}
<a href="/checkout/express">Express checkout</a>
{% else %}
<a href="/checkout">Checkout</a>
{% endsbgate %}
ईजेएस में ब्लॉक मददगार नहीं हैं, लेकिन स्थानीय फ़ंक्शन बहुत से मामलों को साफ ढूंढते हैं
// RISK_ORDER - same map defined in the Handlebars section above
app.use((req, res, next) => {
const v = res.locals.sbVerdict ?? null;
res.locals.sbBelowRisk = (max: string) =>
!v || RISK_ORDER[v.riskBand] <= RISK_ORDER[max];
res.locals.sbAboveRisk = (min: string) =>
v && RISK_ORDER[v.riskBand] >= RISK_ORDER[min];
res.locals.sbIsBot = () => v?.isBot ?? false;
res.locals.sbBotIs = (type: string) => v?.botType === type;
next();
});
<% if (sbBelowRisk('Low')) { %>
<a href="/checkout/express" class="btn btn-success">Express Checkout</a>
<% } else { %>
<a href="/checkout" class="btn btn-secondary">Checkout</a>
<% } %>
<% if (sbBotIs('AiBot')) { %>
<div class="alert alert-info">AI crawler. Data licensing enquiries via /contact.</div>
<% } %>
जोड़ें {{{sbVerdictScript}}} आपके सजावट शीर्ष के लिए . यह के रूप में रेंडर करता है
<script>window.__sb = {"isBot":false,"botProbability":0.12,"riskBand":"Low","recommendedAction":"Allow",...}</script>
Then load the elements bundle:
<head>
{{{sbVerdictScript}}}
<script type="module" src="/js/sb-elements.js"></script>
</head>
<sb-gate>: जोखिम बैंड के अनुसार सामग्री दिखाएँ या छुपाएं<!-- only shown when riskBand <= 'low' -->
<sb-gate max-risk="low">
<a href="/checkout/express" class="btn btn-success">Express Checkout</a>
</sb-gate>
<!-- only shown when riskBand >= 'elevated' -->
<sb-gate min-risk="elevated">
<div class="alert alert-warning">Unusual activity detected on your session.</div>
</sb-gate>
<sb-adapt>: पहले मिलते हुए केस चुनें<sb-adapt>
<sb-case max-risk="low">
Standard checkout - enter your card details below.
</sb-case>
<sb-case max-risk="medium">
Additional verification is required before we can process your order.
</sb-case>
<sb-case>
Automated checkout access is not permitted.
</sb-case>
</sb-adapt>
<sb-adapt> पहला चुनता है <sb-case> जिसके max-risk बाकी को मिलाता है और छुपाता है <sb-case> बिना max-risk कैच है <sb-gate> और <sb-adapt> के लिए सुनो sb:verdict घटना और re-evaluate यदि निर्णय पहले रंग के बाद बदलता है
<sb-widget>: सर्वर<sb-gate> अंतर्वस्तु क्लाइंट छुपाता है-साइड. यदि आप को भिन्न मार्कअप प्राप्त करने के लिए एक बोट की आवश्यकता है तो आपको टेम्प्लेट में उपलब्ध खोज संदर्भ के साथ सर्वर पर रेंडर किए जाने वाले खंड की जरूरत है
<sb-widget> एक इनलाइन से एक तरल टेम्प्लेट पढ़ता है <template> तत्व, पृष्ठ पर सभी विजेट अनुरोधों को एक एकल चक्र में बैच करता है।
<sb-widget data-sb-widget="checkout-cta">
<template>
{% if recommendedAction == 'Block' %}
<p class="text-danger">Automated checkout is blocked.</p>
{% elsif botType == 'AiBot' %}
<p>AI crawlers cannot complete purchases. <a href="/contact">Data licensing enquiries</a>.</p>
{% elsif isBot %}
<p class="text-muted">Checkout is available to human visitors.</p>
{% else %}
<a href="/checkout/express" class="btn btn-success">Express Checkout</a>
{% endif %}
</template>
</sb-widget>
टेम्प्लेट चर isBot, botProbability, confidence, botType, botName, riskBand, recommendedAction, threatScore, threatBand. प्लस कोई भी vars आप कॉल करते समय सर्वर-साइड से गुजरते हैं RenderWidget सीधा
सभी <sb-widget> एक ही माइक्रोटास्क टिक में जुड़ने वाले तत्वों को एक अनुरोध में बैच किया जाता है
sequenceDiagram
participant B as Browser
participant C as Coordinator
participant S as /_stylobot/partials/render
participant L as Fluid / Liquid
B->>C: sb-widget#checkout-cta registers
B->>C: sb-widget#promo-banner registers
B->>C: sb-widget#nav-links registers
Note over C: queueMicrotask - one batch
C->>S: POST { widgets: { checkout-cta: "...", promo-banner: "...", nav-links: "..." } }
S->>L: render each template with verdict context
L-->>S: rendered HTML fragments
S-->>C: <div data-sb-widget="checkout-cta">...</div> ...
C-->>B: each sb-widget replaced in DOM
अवयव
|---|---|---|
| styloBotMiddleware एक्सप्रैस | संलग्नक req.stylobot हेडरों के माध्यम से / gRPC
| styloBotPlugin | फस्टीफ़ाइफ़ करें decorateRequest |
| sbVerdictInjector Express | जनसंख्या res.locals.sbVerdict और sbVerdictScript |
हैंडलबार सहायक | सर्वर टेम्प्लेट sbGate, sbIsBot, sbBotType, sbMinRisk ब्लॉक सहायक |
विस्तार | Nunjucks {% sbgate "Low" %}...{% endsbgate %} |
EJS लोकल | सर्वर टेम्प्लेट sbBelowRisk(), sbAboveRisk(), sbIsBot(), sbBotIs() |
| <sb-gate> ब्राउज़र sb:verdict |
| <sb-adapt> ब्राउज़र
| <sb-widget> ब्राउज़र
| StyloBotGrpcClient नोड
जारी श्रृंखला में अगला: साइडकार वास्तुकला, कैसे पता लगाने की इंजन गैर से कनेक्ट करता है
यदि आप यहाँ से पहुँचे हैं .NET पक्ष से व्यवहार-Aware ASP.NET UI टैग मददगार और कार्य फिल्टर के साथ एक ही स्टोर फ्रंट पैटर्न को कवर करता है लंबे समय तक चलाने वाले नेट सेवाओं में असीमित विकास का पता लगाना और स्थिर करना. लाइव इंजन stylobot.net.
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.