@sohu-bpd/wechat
WeChat JS-SDK utility library with initialization helpers and SPA support.
Features
- 🔄 SPA Support - Auto re-initialization on URL changes for single-page apps
- 📱 iOS Compatible - Handles iOS WeChat signature URL quirks automatically
- 🎯 High-level APIs - Simple
config() and share() APIs for common tasks
- 📦 TypeScript - Full type definitions included
- 🌐 Multiple Formats - ESM, CommonJS, and IIFE bundles
Installation
npm install @sohu-bpd/wechat
pnpm add @sohu-bpd/wechat
yarn add @sohu-bpd/wechat
Quick Start
1. Load WeChat JS-SDK
First, include the WeChat JS-SDK script in your HTML:
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
2. Configure (Optional on Sohu Domains)
Option A: Zero Configuration (Sohu Domains Only)
If you're on https://act.go.sohu.com or https://test.r.ads.sohu.com, you can skip configuration entirely:
import { share } from '@sohu-bpd/wechat'
await share({
title: 'My Page Title',
desc: 'Share description',
imgUrl: 'https://example.com/image.jpg',
})
Option B: Custom Configuration (Sohu Domains)
Or customize settings on supported domains:
import { config } from '@sohu-bpd/wechat'
config({
debug: false,
spa: true,
})
Option C: Custom Signature Function (Other Domains)
For other domains or custom backends:
import { config } from '@sohu-bpd/wechat'
config({
getSignature: async (url) => {
const response = await fetch(`/api/wechat/signature?url=${encodeURIComponent(url)}`)
return response.json()
},
debug: false,
spa: true,
})
3. Use Anywhere
import { share } from '@sohu-bpd/wechat'
await share({
title: 'My Page Title',
desc: 'Share description',
imgUrl: 'https://example.com/image.jpg',
link: 'https://example.com/page',
})
Usage
ESM / CommonJS
import { config, share } from '@sohu-bpd/wechat'
const { config, share } = require('@sohu-bpd/wechat')
Browser (IIFE)
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
<script src="https://unpkg.com/@sohu-bpd/wechat/dist/index.global.js"></script>
<script>
const { config, share } = SohuWechat
config({
getSignature: async (url) => {
const res = await fetch('/api/wechat/signature?url=' + encodeURIComponent(url))
return res.json()
}
})
share({
title: 'My Page',
desc: 'Description',
imgUrl: 'https://example.com/image.jpg'
})
</script>
API Reference
High-level APIs
config(options)
Set global configuration for WeChat JS-SDK.
Note:
- You must load the WeChat JS-SDK script in your HTML before using this library
- On
https://act.go.sohu.com or https://test.r.ads.sohu.com, calling config() is optional - the library will auto-configure with defaults when you use features like share()
interface GlobalConfig {
getSignature?: (url: string) => Promise<SignatureResult>
debug?: boolean
spa?: boolean
}
function config(options?: GlobalConfig): void
Example - No configuration needed (Sohu domains):
import { share } from '@sohu-bpd/wechat'
await share({
title: 'My Page',
desc: 'Description',
imgUrl: 'https://example.com/image.jpg',
})
Example - Custom signature function:
config({
getSignature: async (url) => {
const res = await fetch(`/api/wechat/signature?url=${encodeURIComponent(url)}`)
return res.json()
},
debug: process.env.NODE_ENV === 'development',
spa: true,
})
Example - Custom settings with built-in signature (Sohu domains):
config({
debug: true,
spa: true,
})
share(options)
Set WeChat share content for both friends and moments.
interface ShareOptions {
title: string
desc?: string
link?: string
imgUrl: string
}
function share(options: ShareOptions): Promise<void>
Example:
await share({
title: 'Amazing Product',
desc: 'Check out this amazing product!',
imgUrl: 'https://example.com/product.jpg',
link: 'https://example.com/product/123',
})
getConfig()
Get current global configuration (throws if not configured).
function getConfig(): GlobalConfig
isConfigured()
Check if global configuration has been set.
function isConfigured(): boolean
Low-level APIs
For advanced use cases, you can use the low-level APIs:
initSDK(jsApiList)
Initialize WeChat SDK with specified APIs (automatically called by high-level APIs).
Note: Requires WeChat JS-SDK to be loaded globally first.
function initSDK(jsApiList: string[]): Promise<void>
getWx()
Get the global wx object after SDK is loaded.
function getWx(): any
resetSDK()
Reset SDK state (useful for testing or manual re-initialization).
function resetSDK(): void
Original init Function
For use cases that don't need global configuration.
Note: Requires WeChat JS-SDK to be loaded globally first.
interface InitConfig {
appId: string
timestamp: number | string
nonceStr: string
signature: string
jsApiList: string[]
debug?: boolean
}
function init(config: InitConfig): Promise<void>
SPA Mode
By default, spa: true is enabled, which means:
- On the first API call (e.g.,
share()), the SDK is initialized with the current URL
- On subsequent API calls, if the URL has changed, the SDK is automatically re-initialized
- This is essential for single-page applications where the URL changes without page reloads
To disable SPA mode:
config({
spa: false,
})
Built-in Signature Support
On specific Sohu domains, the library provides built-in signature functionality:
Supported Domains
https://act.go.sohu.com
https://test.r.ads.sohu.com
How It Works
When you call config() without providing getSignature on a supported domain:
- The library automatically detects the current domain
- Uses the built-in signature function that requests
/wechat/ticket
- Converts the API response to the standard
SignatureResult format
API Request Format
The built-in signature function sends a GET request to:
/wechat/ticket?url={encoded_current_url}
Parameters:
url (query parameter): The current page URL (URL-encoded)
Example Request:
GET /wechat/ticket?url=https%3A%2F%2Fact.go.sohu.com%2Fpage%3Fid%3D123
API Response Format
The built-in signature endpoint /wechat/ticket should return:
{
code: number
data: {
app_id: string
timestamp: number
nonce_str: string
signature: string
}
message: string
}
Notes:
- Uses
fetch API if available (modern browsers)
- Automatically falls back to
XMLHttpRequest in older environments
- Response format is automatically converted to match
SignatureResult interface
Usage
Zero Configuration (Recommended):
import { share } from '@sohu-bpd/wechat'
await share({
title: 'My Page',
desc: 'Description',
imgUrl: 'https://example.com/image.jpg',
})
With Custom Settings:
import { config, share } from '@sohu-bpd/wechat'
config({
debug: true,
spa: true,
})
await share({
title: 'My Page',
desc: 'Description',
imgUrl: 'https://example.com/image.jpg',
})
Fallback to Custom Function
Even on supported domains, you can provide your own getSignature function:
config({
getSignature: async (url) => {
return await fetchSignatureFromCustomAPI(url)
},
})
iOS WeChat Quirk
On iOS WeChat, the signature URL should be the first entry URL of the app, not the current URL. This library handles this automatically:
- On iOS, it remembers the first URL and always uses it for signatures
- On Android, it uses the current URL for each signature request
You don't need to do anything special - it just works.
Backend Signature Endpoint
Your backend should provide an endpoint that generates WeChat JS-SDK signatures. Here's an example implementation:
app.get('/api/wechat/signature', async (req, res) => {
const url = req.query.url as string
const signature = await generateWeChatSignature(url)
res.json({
appId: 'your-app-id',
timestamp: signature.timestamp,
nonceStr: signature.nonceStr,
signature: signature.signature,
})
})
Refer to WeChat JS-SDK Documentation for signature generation details.
TypeScript Support
Full TypeScript definitions are included:
import type {
GlobalConfig,
SignatureResult,
ShareOptions
} from '@sohu-bpd/wechat'
const config: GlobalConfig = {
sdkUrl: '...',
getSignature: async (url: string): Promise<SignatureResult> => {
}
}
Bundle Formats
- ESM (
.mjs) - Modern JavaScript modules
- CommonJS (
.js) - Node.js and bundlers
- IIFE (
.global.js) - Browser <script> tag with global SohuWechat
Changelog
0.0.4 (TBD)
- New Feature: Built-in signature support for Sohu domains
- Zero Configuration Mode: On
https://act.go.sohu.com and https://test.r.ads.sohu.com, you can now use the library without calling config() at all
getSignature is now optional on supported domains
- Automatic signature fetching from
/wechat/ticket?url={current_url} endpoint on supported domains
- Built-in request uses
fetch API with automatic fallback to XMLHttpRequest for older browsers
- Added comprehensive tests for built-in signature functionality, xhr fallback, and auto-initialization
0.0.3 (2026-01-29)
- Breaking Change: Removed automatic SDK loading functionality
- Users must now manually include the WeChat JS-SDK script in their HTML
- Removed
sdkUrl configuration option from GlobalConfig
- Removed
loadSDK() export from public API
- Updated documentation with instructions for manual SDK inclusion
0.0.2 (2026-01-29)
- Extract WeChat JS-SDK module as standalone package
- High-level
config() and share() APIs
- Automatic SDK loading and initialization
- SPA mode with auto re-initialization on URL changes
- iOS WeChat signature URL handling
- Full TypeScript support
- Comprehensive unit tests
- Multiple bundle formats (ESM, CJS, IIFE)
License
MIT