
X Request
- 59 installs
- 4.7k repo stars
- Updated August 4, 2026
- ant-design/x
x-request is a Claude Code skill for configuring XRequest from @ant-design/x-sdk, the tool that handles network requests, auth, retries, and streaming for Ant Design X chat apps.
About
This skill explains how to configure XRequest from @ant-design/x-sdk, the request tool that handles network communication, authentication, error handling, and streaming for Ant Design X chat apps. A developer uses it to set up transport, auth headers, retries, and SSE or JSON streaming for a chat interface. It includes a security guide on keeping API keys out of the browser and using proxy forwarding instead.
- Configures XRequest for streaming chat transport, auth, and retries
- Documents SSE and JSON streaming plus per-environment security guidance
- Warns against configuring API keys in the browser frontend
X Request by the numbers
- 59 all-time installs (skills.sh)
- Ranked #1,216 of 2,245 Frontend Development skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
x-request capabilities & compatibility
- Capabilities
- request config · streaming adapter · auth setup
- Works with
- openai
- Use cases
- frontend · api development
What x-request says it does
This skill focuses on solving**: How to correctly configure XRequest to adapt to various streaming interface requirements.
Browser Frontend** | 🔴 High Risk | ❌ Prohibit key configuration | Keys will be directly exposed to users
npx skills add https://github.com/ant-design/x --skill x-requestAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 59 |
|---|---|
| repo stars | ★ 4.7k |
| Last updated | August 4, 2026 |
| Repository | ant-design/x ↗ |
What it does
Configure XRequest transport, auth, and streaming for an Ant Design X React chat app.
Who is it for?
Configuring transport, auth, retries, and streaming separators for an Ant Design X chat app
Skip if: Managing chat state or rendering markdown, which other x-* skills cover
When should I use this skill?
You need to configure request transport, authentication, or streaming for Ant Design X
What you get
A correctly configured XRequest instance with safe key handling
- Configured XRequest instance
By the numbers
- Requires @ant-design/x-sdk version >= 2.2.2
Files
🎯 Skill Positioning
This skill focuses on solving: How to correctly configure XRequest to adapt to various streaming interface requirements.
Table of Contents
- 🚀 Quick Start - Get started in 3 minutes
- Dependency Management
- Basic Configuration
- 📦 Technology Stack Overview
- 🔧 Core Configuration Details
- Global Configuration
- Security Configuration
- Streaming Configuration
- 🛡️ Security Guide
- Environment Security Configuration
- Authentication Methods Comparison
- 🔍 Debugging and Testing
- Debug Configuration
- Configuration Validation
- 📋 Usage Scenarios
- Standalone Usage
- Integration with Other Skills
- 🚨 Development Rules
- 🔗 Reference Resources
- 📚 Core Reference Documentation
- 🌐 SDK Official Documentation
- 💻 Example Code
🚀 Quick Start
Dependency Management
📋 System Requirements
| Package | Version Requirement | Auto Install | Purpose |
|---|---|---|---|
| @ant-design/x-sdk | ≥2.2.2 | ✅ | Core SDK, includes XRequest tool |
🛠️ One-click Installation
# Recommended to use tnpm
tnpm install @ant-design/x-sdk
# Or use npm
npm add @ant-design/x-sdk
# Check version
npm ls @ant-design/x-sdkBasic Configuration
Simplest Usage
import { XRequest } from '@ant-design/x-sdk';
// Minimal configuration: only need to provide API URL
const request = XRequest('https://api.example.com/chat');
// For manual control (used in Provider scenarios)
const providerRequest = XRequest('https://api.example.com/chat', {
manual: true, // Usually only this needs explicit configuration
});💡 Tip: XRequest has built-in reasonable default configurations. In most cases, you only need to provide the API URL to use it.
📦 Technology Stack Overview
🏗️ Technology Stack Architecture
graph TD
A[XRequest] --> B[Network Requests]
A --> C[Authentication Management]
A --> D[Error Handling]
A --> E[Streaming Processing]
B --> F[fetch Wrapper]
C --> G[Token Management]
D --> H[Retry Mechanism]
E --> I[Server-Sent Events]🔑 Core Concepts
| Concept | Role Positioning | Core Responsibilities | Usage Scenarios |
|---|---|---|---|
| XRequest | 🌐 Request Tool | Handle all network communication, authentication, error handling | Unified request management |
| Global Config | ⚙️ Config Center | Configure once, use everywhere | Reduce duplicate code |
| Streaming Config | 🔄 Streaming Processing | Support SSE and JSON response formats | AI conversation scenarios |
🔧 Core Configuration Details
Core functionality reference content CORE.md
🛡️ Security Guide
Environment Security Configuration
🌍 Security Strategies for Different Environments
| Runtime Environment | Security Level | Configuration Method | Risk Description |
|---|---|---|---|
| Browser Frontend | 🔴 High Risk | ❌ Prohibit key configuration | Keys will be directly exposed to users |
| Node.js Backend | 🟢 Safe | ✅ Environment variable configuration | Keys stored on server side |
| Proxy Service | 🟢 Safe | ✅ Same-origin proxy forwarding | Keys managed by proxy service |
🔐 Authentication Methods Comparison
| Authentication Method | Applicable Environment | Configuration Example | Security |
|---|---|---|---|
| Bearer Token | Node.js | Bearer ${process.env.API_KEY} | ✅ Safe |
| API Key Header | Node.js | X-API-Key: ${process.env.KEY} | ✅ Safe |
| Proxy Forwarding | Browser | /api/proxy/service | ✅ Safe |
| Direct Configuration | Browser | Bearer sk-xxx | ❌ Dangerous |
🔍 Debugging and Testing
Debug Configuration
🛠️ Debug Templates
Node.js Debug Configuration:
// Safe debug configuration (Node.js environment)
const debugRequest = XRequest('https://your-api.com/chat', {
headers: {
Authorization: `Bearer ${process.env.DEBUG_API_KEY}`,
},
params: { query: 'test message' },
});Frontend Debug Configuration:
// Safe debug configuration (frontend environment)
const debugRequest = XRequest('/api/debug/chat', {
params: { query: 'test message' },
});Configuration Validation
✅ Security Check Tools
// Security configuration validation function
const validateSecurity = (config: any) => {
const isBrowser = typeof window !== 'undefined';
const hasAuth = config.headers?.Authorization || config.headers?.authorization;
if (isBrowser && hasAuth) {
throw new Error(
'❌ Frontend environment prohibits Authorization configuration, risk of key leakage!',
);
}
console.log('✅ Security configuration check passed');
return true;
};
// Usage example
validateSecurity({
headers: {
// Do not include Authorization
},
});📋 Usage Scenarios
Standalone Usage
🎯 Direct Request Initiation
import { XRequest } from '@ant-design/x-sdk';
// Test interface availability
const testRequest = XRequest('https://httpbin.org/post', {
params: { test: 'data' },
});
// Send request immediately
const response = await testRequest();
console.log(response);Integration with Other Skills
🔄 Skill Collaboration Workflow
graph TD
A[x-request] -->|Configure Request| B[x-chat-provider]
A -->|Configure Request| C[use-x-chat]
B -->|Provide Provider| C
A --> D[Direct Request]| Usage Method | Cooperating Skill | Purpose | Example |
|---|---|---|---|
| Standalone | None | Direct network request initiation | Test interface availability |
| With x-chat-provider | x-chat-provider | Configure requests for custom Provider | Configure private API |
| With use-x-chat | use-x-chat | Configure requests for built-in Provider | Configure OpenAI API |
| Complete AI Application | x-request → x-chat-provider → use-x-chat | Configure requests for entire system | Complete AI conversation application |
⚠️ useXChat Integration Security Warning
Important Warning: useXChat is only for frontend environments, XRequest configuration must not contain Authorization!
❌ Incorrect Configuration (Dangerous):
// Extremely dangerous: keys will be directly exposed to browser
const unsafeRequest = XRequest('https://api.openai.com/v1/chat/completions', {
headers: {
Authorization: 'Bearer sk-xxxxxxxxxxxxxx', // ❌ Dangerous!
},
manual: true,
});✅ Correct Configuration (Safe):
// Frontend security configuration: use proxy service
const safeRequest = XRequest('/api/proxy/openai', {
params: {
model: 'gpt-3.5-turbo',
stream: true,
},
manual: true,
});🚨 Development Rules
Test Case Rules
- If the user does not explicitly need test cases, do not add test files
- Only create test cases when the user explicitly requests them
Code Quality Rules
- After completion, must check types: Run
tsc --noEmitto ensure no type errors - Keep code clean: Remove all unused variables and imports
✅ Configuration Checklist
Before using XRequest, please confirm the following configurations are correctly set:
🔍 Configuration Checklist
| Check Item | Status | Description |
|---|---|---|
| API URL | ✅ Must Configure | XRequest('https://api.xxx.com') |
| Auth Info | ⚠️ Environment Related | Frontend❌Prohibited, Node.js✅Available |
| manual Config | ✅ Provider Scenario | In Provider needs to be set to true, other scenarios need to be set according to actual situation |
| Other Config | ❌ No Need to Configure | Built-in reasonable default values |
| Interface Availability | ✅ Recommended Test | Verify with debug configuration |
🛠️ Quick Verification Script
// Check configuration before running
const checkConfig = () => {
const checks = [
{
name: 'Global Configuration',
test: () => {
// Check if global configuration has been set
return true; // Check according to actual situation
},
},
{
name: 'Security Configuration',
test: () => validateSecurity(globalConfig),
},
{
name: 'Type Check',
test: () => {
// Run tsc --noEmit
return true;
},
},
];
checks.forEach((check) => {
console.log(`${check.name}: ${check.test() ? '✅' : '❌'}`);
});
};🎯 Skill Collaboration
graph LR
A[x-request] -->|Configure Request| B[x-chat-provider]
A -->|Configure Request| C[use-x-chat]
B -->|Provide Provider| C📊 Skill Usage Comparison Table
| Usage Scenario | Required Skills | Usage Order | Completion Time |
|---|---|---|---|
| Test Interface | x-request | Direct Use | 2 minutes |
| Private API Adaptation | x-request → x-chat-provider | Configure request first, then create Provider | 10 minutes |
| Standard AI Application | x-request → use-x-chat | Configure request first, then build interface | 15 minutes |
| Complete Customization | x-request → x-chat-provider → use-x-chat | Complete workflow | 30 minutes |
🔗 Reference Resources
📚 Core Reference Documentation
- API.md - Complete API reference documentation
- EXAMPLES_SERVICE_PROVIDER.md - Configuration examples for various service providers
🌐 SDK Official Documentation
💻 Example Code
- custom-provider-width-ui.tsx - Complete example of custom Provider
XRequestFunction
```ts | pure type XRequestFunction<Input = Record<PropertyKey, any>, Output = Record<string, string>> = ( baseURL: string, options?: XRequestOptions<Input, Output>, ) => XRequestClass<Input, Output>;
### XRequestFunction
| Property | Description | Type | Default | Version |
| -------- | ---------------- | -------------------------------- | ------- | ------- |
| baseURL | API endpoint URL | string | - | - |
| options | Request options | XRequestOptions\<Input, Output\> | - | - |
### XRequestOptions
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| callbacks | Request callback handlers | XRequestCallbacks\<Output\> | - | - |
| params | Request parameters | Input | - | - |
| headers | Additional request headers | Record\<string, string\> | - | - |
| timeout | Request timeout configuration (time from sending request to connecting to service), unit: ms | number | - | - |
| streamTimeout | Stream mode data timeout configuration (time interval for each chunk return), unit: ms | number | - | - |
| fetch | Custom fetch object | `typeof fetch` | - | - |
| middlewares | Middlewares for pre- and post-request processing | XFetchMiddlewares | - | - |
| transformStream | Stream processor | XStreamOptions\<Output\>['transformStream'] \| ((baseURL: string, responseHeaders: Headers) => XStreamOptions\<Output\>['transformStream']) | - | - |
| streamSeparator | Stream separator, used to separate different data streams. Does not take effect when transformStream has a value | string | \n\n | 2.2.0 |
| partSeparator | Part separator, used to separate different parts of data. Does not take effect when transformStream has a value | string | \n | 2.2.0 |
| kvSeparator | Key-value separator, used to separate keys and values. Does not take effect when transformStream has a value | string | : | 2.2.0 |
| manual | Whether to manually control request sending. When `true`, need to manually call `run` method | boolean | false | - |
| retryInterval | Retry interval when request is interrupted or fails, in milliseconds. If not set, automatic retry will not occur | number | - | - |
| retryTimes | Maximum number of retry attempts. No further retries will be attempted after exceeding this limit | number | - | - |
### XRequestCallbacks
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| onSuccess | Success callback. When used with Chat Provider, additionally gets the assembled message | (chunks: Output[], responseHeaders: Headers, message: ChatMessage) => void | - | - |
| onError | Error handling callback. `onError` can return a number indicating the retry interval (in milliseconds) when a request exception occurs. When both `onError` return value and `options.retryInterval` exist, the `onError` return value takes precedence. When used with Chat Provider, additionally gets the assembled fail back message | (error: Error, errorInfo: any, responseHeaders?: Headers, message: ChatMessage) => number \| void | - | - |
| onUpdate | Message update callback. When used with Chat Provider, additionally gets the assembled message | (chunk: Output, responseHeaders: Headers, message: ChatMessage) => void | - | - |
### XRequestClass
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| abort | Cancel request | () => void | - | - |
| run | Manually execute request (effective when `manual=true`) | (params?: Input) => void | - | - |
| isRequesting | Whether currently requesting | boolean | - | - |
### setXRequestGlobalOptions
type setXRequestGlobalOptions<Input, Output> = ( options: XRequestGlobalOptions<Input, Output>, ) => void;
### XRequestGlobalOptions
type XRequestGlobalOptions<Input, Output> = Pick< XRequestOptions<Input, Output>, 'headers' | 'timeout' | 'streamTimeout' | 'middlewares' | 'fetch' | 'transformStream' | 'manual' >;
### XFetchMiddlewares
interface XFetchMiddlewares { onRequest?: (...ags: Parameters<typeof fetch>) => Promise<Parameters<typeof fetch>>; onResponse?: (response: Response) => Promise<Response>; }
## FAQ
### When using transformStream in XRequest, it causes stream locking issues on the second input request. How to solve this?
onError TypeError: Failed to execute 'getReader' on 'ReadableStream': ReadableStreamDefaultReader constructor can only accept readable streams that are not yet locked to a reader
The Web Streams API stipulates that a stream can only be locked by one reader at the same time. Reuse will cause an error. Therefore, when using TransformStream, you need to pay attention to the following points:
1. Ensure that the transformStream function returns a new ReadableStream object, not the same object.
2. Ensure that the transformStream function does not perform multiple read operations on response.body.
**Recommended Writing**
const [provider] = React.useState( new CustomProvider({ request: XRequest(url, { manual: true, // Recommended: transformStream returns a new instance with a function transformStream: () => new TransformStream({ transform(chunk, controller) { // Your custom processing logic controller.enqueue({ data: chunk }); }, }), // Other configurations... }), }), );
const request = XRequest(url, { manual: true, transformStream: new TransformStream({ ... }), // Do not persist in Provider/useState });
1. Built-in Default Configuration
XRequest has built-in reasonable default configurations, no additional configuration needed to use.
Built-in Default Values:
method: 'POST'headers: { 'Content-Type': 'application/json' }
2. Security Configuration
🔐 Authentication Configuration Comparison
| Environment Type | Configuration Method | Security | Example |
|---|---|---|---|
| Frontend Browser | ❌ Prohibit direct configuration | Dangerous | Keys will be exposed to users |
| Node.js | ✅ Environment variables | Safe | process.env.API_KEY |
| Proxy Service | ✅ Same-origin proxy | Safe | /api/proxy/chat |
🛡️ Security Configuration Templates
Node.js Environment Security Configuration:
const nodeConfig = {
baseURL: 'https://api.openai.com/v1',
headers: {
Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
},
};Frontend Environment Security Configuration:
const browserConfig = {
baseURL: '/api/proxy/openai', // Through same-origin proxy
};3. Basic Usage
import { XRequest } from '@ant-design/x-sdk';
// ⚠️ Note: The following examples apply to Node.js environment
// Frontend environments should use proxy services to avoid token leakage
const request = XRequest('https://your-api.com/chat', {
headers: {
Authorization: 'Bearer your-token', // ⚠️ Only for Node.js environment
},
params: {
query: 'Hello',
},
manual: true, // ⚠️ Must be set to true when used in provider
callbacks: {
onSuccess: (messages) => {
setStatus('success');
console.log('onSuccess', messages);
},
onError: (error) => {
setStatus('error');
console.error('onError', error);
},
onUpdate: (msg) => {
setLines((pre) => [...pre, msg]);
console.log('onUpdate', msg);
},
},
});⚠️ Important Reminder: When XRequest is used in x-chat-provider or use-x-chat provider, manual: true is a required configuration, otherwise the request will be sent immediately instead of waiting for invocation.````
With URL Parameters
const request = XRequest('https://your-api.com/chat', {
method: 'GET',
params: {
model: 'gpt-3.5-turbo',
max_tokens: 1000,
},
});4. Streaming Configuration
🔄 Streaming Response Configuration
// Streaming response configuration (AI conversation scenarios)
const streamConfig = {
params: {
stream: true, // Enable streaming response
model: 'gpt-3.5-turbo',
max_tokens: 1000,
},
manual: true, // Manual control of requests
};
// Non-streaming response configuration (regular API scenarios)
const jsonConfig = {
params: {
stream: false, // Disable streaming response
},
};5. Dynamic Request Headers
// ❌ Unsafe: Frontend directly exposes API key
// const request = XRequest('https://your-api.com/chat', {
// headers: {
// 'Authorization': `Bearer ${apiKey}`, // Don't do this!
// },
// params: {
// messages: [{ role: 'user', content: 'Hello' }],
// },
// });
// ✅ Safe: Node.js environment uses environment variables
const request = XRequest('https://your-api.com/chat', {
headers: {
Authorization: `Bearer ${process.env.API_KEY}`, // Safe for Node.js environment
},
params: {
messages: [{ role: 'user', content: 'Hello' }],
},
});
// ✅ Safe: Frontend uses proxy service
const request = XRequest('/api/proxy/chat', {
headers: {
// No Authorization needed, handled by backend proxy
},
params: {
messages: [{ role: 'user', content: 'Hello' }],
},
});6. Custom Stream Transformers
When AI service providers return non-standard formats, use transformStream for custom data transformation.
Basic Example
const request = XRequest('https://api.example.com/chat', {
params: { message: 'Hello' },
transformStream: () =>
new TransformStream({
transform(chunk, controller) {
// TextDecoder converts binary data to string
const text = new TextDecoder().decode(chunk);
const lines = text.split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = line.slice(6);
if (data !== '[DONE]') {
// TextEncoder converts string back to binary
controller.enqueue(new TextEncoder().encode(data));
}
}
}
},
}),
});Common Transformation Templates
// OpenAI format
const openaiStream = () =>
new TransformStream({
transform(chunk, controller) {
const text = new TextDecoder().decode(chunk);
const data = JSON.parse(text);
const content = data.choices?.[0]?.delta?.content || '';
controller.enqueue(new TextEncoder().encode(content));
},
});
// Usage example
const request = XRequest(url, {
params: { message: 'Hello' },
transformStream: openaiStream,
});⚠️ Note: ReadableStream can only be locked by one reader, avoid reusing the same instance.
🔍 TextDecoder/TextEncoder Explanation
When are they needed?
| Scenario | Data Type | Need Conversion? |
|---|---|---|
| Standard fetch API | Uint8Array binary | ✅ Need TextDecoder |
| XRequest wrapper | May be string | ❌ May not need |
| Custom stream processing | Depends on implementation | 🤔 Need to determine type |
Practical Usage Suggestions:
transformStream: () =>
new TransformStream({
transform(chunk, controller) {
// Safe approach: check type first
const text = typeof chunk === 'string' ? chunk : new TextDecoder().decode(chunk);
// Now text is definitely a string
controller.enqueue(text);
},
});1️⃣ OpenAI Standard Format
Node.js Environment (Safe)
const openAIRequest = XRequest('https://api.example-openai.com/v1/chat/completions', {
headers: {
Authorization: `Bearer ${process.env.OPENAI_API_KEY}`, // Node.js environment variable
},
params: {
model: 'gpt-3.5-turbo',
messages: [{ role: 'user', content: 'Hello' }],
stream: true,
},
});Frontend Environment (Using Proxy)
// ❌ Dangerous: Do not configure token directly in frontend
// const openAIRequest = XRequest('https://api.example-openai.com/v1/chat/completions', {
// headers: {
// 'Authorization': 'Bearer sk-xxxxxxxx', // ❌ Will expose key
// },
// });
// ✅ Safe: Through same-origin proxy
const openAIRequest = XRequest('/api/proxy/openai', {
params: {
model: 'gpt-3.5-turbo',
messages: [{ role: 'user', content: 'Hello' }],
stream: true,
},
});2️⃣ Alibaba Cloud Bailian (Tongyi Qianwen)
const bailianRequest = XRequest(
'https://api.example-aliyun.com/api/v1/services/aigc/text-generation/generation',
{
headers: {
Authorization: 'Bearer API_KEY',
},
params: {
model: 'qwen-turbo',
input: {
messages: [{ role: 'user', content: 'Hello' }],
},
parameters: {
result_format: 'message',
incremental_output: true,
},
},
},
);3️⃣ Baidu Qianfan (Wenxin Yiyan)
const qianfanRequest = XRequest(
'https://api.example-baidu.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions',
{
params: {
messages: [{ role: 'user', content: 'Hello' }],
stream: true,
},
},
);4️⃣ Zhipu AI (ChatGLM)
const zhipuRequest = XRequest('https://api.example-zhipu.com/api/paas/v4/chat/completions', {
headers: {
Authorization: 'Bearer API_KEY',
},
params: {
model: 'glm-4',
messages: [{ role: 'user', content: 'Hello' }],
stream: true,
},
});5️⃣ Xunfei Spark
const sparkRequest = XRequest('https://api.example-spark.com/v1/chat/completions', {
headers: {
Authorization: 'Bearer API_KEY',
},
params: {
model: 'generalv3.5',
messages: [{ role: 'user', content: 'Hello' }],
stream: true,
},
});6️⃣ ByteDance Doubao
const doubaoRequest = XRequest('https://api.example-doubao.com/api/v3/chat/completions', {
headers: {
Authorization: 'Bearer API_KEY',
},
params: {
model: 'doubao-lite-4k',
messages: [{ role: 'user', content: 'Hello' }],
stream: true,
},
});7️⃣ Local Private API
const localRequest = XRequest('http://localhost:3000/api/chat', {
headers: {
'X-API-Key': 'your-local-key',
},
params: {
prompt: 'Hello',
max_length: 1000,
temperature: 0.7,
},
});Related skills
FAQ
Can I put an API key in the browser frontend?
No; the docs mark browser frontend key configuration as high risk because keys are exposed to users. Use Node.js environment variables or same-origin proxy forwarding instead.
What is the minimal XRequest configuration?
In most cases you only need to provide the API URL, since XRequest has built-in reasonable defaults; add manual: true for Provider scenarios.