@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
- 🛡️ Non-WeChat Safe - All APIs silently return in non-WeChat environments without errors
- 📦 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:
isWechat()
Check if the current environment is WeChat browser.
function isWechat(): boolean
Example:
import { isWechat, share } from '@sohu-bpd/wechat'
if (isWechat()) {
showShareButton()
}
await share({
title: 'My Page',
imgUrl: 'https://example.com/image.jpg',
})
initSDK(jsApiList)
Initialize WeChat SDK with specified APIs (automatically called by high-level APIs).
Note: Requires WeChat JS-SDK to be loaded globally first. Silently returns in non-WeChat environments.
function initSDK(jsApiList: string[]): Promise<void>
getWx()
Get the global wx object after SDK is loaded. Returns null in non-WeChat environments or if wx is not available.
function getWx(): WxSDK | null
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)
},
})
Non-WeChat Environment Safety
All APIs are safe to call in non-WeChat environments (desktop browsers, other mobile browsers, SSR, etc.). They will silently return without throwing errors, so your application works normally:
import { share, init, initSDK, isWechat } from '@sohu-bpd/wechat'
await share({
title: 'My Page',
imgUrl: 'https://example.com/image.jpg',
})
await init({
appId: 'wx123',
timestamp: 123,
nonceStr: 'abc',
signature: 'sig',
jsApiList: [],
})
await initSDK(['updateAppMessageShareData'])
if (isWechat()) {
showWeChatShareButton()
}
This design allows you to integrate WeChat sharing without wrapping every call in environment checks.
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.6 (TBD)
- Non-WeChat Safe: All APIs now silently return in non-WeChat environments without throwing errors
- New API: Added
isWechat() function to check if running in WeChat browser
- Breaking Change:
getWx() now returns WxSDK | null instead of throwing errors
share(), init(), and initSDK() resolve immediately in non-WeChat environments
- This allows seamless integration without environment checks around every API call
0.0.5
- 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