Momento Web SDK for JavaScript in browsers
Momento provides two JavaScript SDKs; one for Node.js and one for browsers other web applications (this page). The two SDKs have identical APIs, so your code will look the same except for import
statements, but under the hood they are built for optimal performance and compatibility in different JavaScript runtime environments.
The Node.js SDK is best suited for server-side use cases. The Momento web SDK, however, allows developers to write JavaScript code that runs in a browser and communicates directly with Momento services. This allows you to avoid the typical overhead of building and operating your own web service to mediate cache or pub/sub calls between the browser and Momento. It also means one less hop for your web traffic, so you can get even better performance out of your browser application. The best of both worlds!
You can also use the web SDK in other non-Node.js JavaScript environments.
The Momento web SDK is available via the npm package @gomomento/sdk-web
.
The source code can be found on GitHub: momentohq/client-sdk-javascript.
Requirements
- A Momento API key is required; you can get one from the Momento web console.
Resources
- Getting started with Momento Cache in JavaScript: this cheat sheet targets the Node.js SDK, but the web SDK APIs are fully compatible.
- Getting started with Momento Topics in JavaScript: this cheat sheet targets the Node.js SDK, but the web SDK APIs are fully compatible.
- Getting started with Momento Storage in JavaScript: this cheat sheet targets the Node.js SDK, but the web SDK APIs are fully compatible.
- Chat app: Next.js: a dynamic app that allows users to chat in their browser by entering a cache and topic name. The application vends low scope, short-lived auth tokens to the browser which uses them to subscribe to the topic.
- Chat app: Vite: a static version of the chat app that requires a separate API (such as our Node.js token vending machine) to provide auth tokens to browsers.
- Web SDK Examples: working example projects that illustrate how to use the web SDK
Momento web SDK and Momento Topics
Momento Topics significantly simplifies publisher-subscriber communication in a browser. Traditionally, developers example of this is a chat application embedded in a website; you are not only building the client code for the browser, but the server-side code for routing all the communications.
This server-side complexity is eliminated by incorporating Momento Topics with the Momento web SDK. Developers can subscribe to Momento Topics directly from the browser. Momento then takes care of all communication when messages are published to the topic, eliminating the need for custom server-side infrastructure for WebSockets!
Using the web SDK for browsers
While the API calls are identical to the Momento Node.js SDK, the import/require statement will consume the @gomomento/sdk-web
package from npm, instead of @gomomento/sdk
(which is the Node.js SDK).
Here's an example import statement for the web SDK:
import {CacheClient} from ‘@gomomento/sdk-web’;
Credentials for Browsers
In order for your browser application to communicate with Momento services, you will need to provide the browser with a Momento auth token. The recommended practice is to generate a Momento disposable token that has expiring credentials for each browser session. This enables the app to distribute tokens without worrying about your data being compromised.
To create a Momento disposable token for use in the browser, you will generally need a "token vending machine" component. The token vending machine can be a standalone application with an HTTP endpoint that a static website can access, or it can be a component embedded into the server side of your web application, as in our Next.js chat app example.
In either case, you will likely use the Node.js SDK to instantiate a Momento AuthClient
and provide it an API key with Super User scope generated via the Momento Console:
new AuthClient({
credentialProvider: CredentialProvider.fromEnvironmentVariable('MOMENTO_API_KEY'),
});
Then you will use the generateDisposableToken
API to create a disposable token that you can vend to the browser. These tokens are short-lived by default and they must expire within one hour.
// Generate a disposable token with read-write access to a specific key in one cache
const oneKeyOneCacheToken = await authClient.generateDisposableToken(
DisposableTokenScopes.cacheKeyReadWrite('squirrels', 'mo'),
ExpiresIn.minutes(30)
);
switch (oneKeyOneCacheToken.type) {
case GenerateDisposableTokenResponse.Success:
console.log('Generated a disposable API key with access to the "mo" key in the "squirrels" cache!');
// logging only a substring of the tokens, because logging security credentials is not advisable :)
console.log(`API key starts with: ${oneKeyOneCacheToken.authToken.substring(0, 10)}`);
console.log(`Expires At: ${oneKeyOneCacheToken.expiresAt.epoch()}`);
break;
case GenerateDisposableTokenResponse.Error:
throw new Error(
`An error occurred while attempting to call generateApiKey with disposable token scope: ${oneKeyOneCacheToken.errorCode()}: ${oneKeyOneCacheToken.toString()}`
);
}
// Generate a disposable token with read-write access to a specific key prefix in all caches
const keyPrefixAllCachesToken = await authClient.generateDisposableToken(
DisposableTokenScopes.cacheKeyPrefixReadWrite(AllCaches, 'squirrel'),
ExpiresIn.minutes(30)
);
switch (keyPrefixAllCachesToken.type) {
case GenerateDisposableTokenResponse.Success:
console.log('Generated a disposable API key with access to keys prefixed with "squirrel" in all caches!');
// logging only a substring of the tokens, because logging security credentials is not advisable :)
console.log(`API key starts with: ${keyPrefixAllCachesToken.authToken.substring(0, 10)}`);
console.log(`Expires At: ${keyPrefixAllCachesToken.expiresAt.epoch()}`);
break;
case GenerateDisposableTokenResponse.Error:
throw new Error(
`An error occurred while attempting to call generateApiKey with disposable token scope: ${keyPrefixAllCachesToken.errorCode()}: ${keyPrefixAllCachesToken.toString()}`
);
}
// Generate a disposable token with read-only access to all topics in one cache
const allTopicsOneCacheToken = await authClient.generateDisposableToken(
TokenScopes.topicSubscribeOnly('squirrel', AllTopics),
ExpiresIn.minutes(30)
);
switch (allTopicsOneCacheToken.type) {
case GenerateDisposableTokenResponse.Success:
console.log('Generated a disposable API key with access to all topics in the "squirrel" cache!');
// logging only a substring of the tokens, because logging security credentials is not advisable :)
console.log(`API key starts with: ${allTopicsOneCacheToken.authToken.substring(0, 10)}`);
console.log(`Expires At: ${allTopicsOneCacheToken.expiresAt.epoch()}`);
break;
case GenerateDisposableTokenResponse.Error:
throw new Error(
`An error occurred while attempting to call generateApiKey with disposable token scope: ${allTopicsOneCacheToken.errorCode()}: ${allTopicsOneCacheToken.toString()}`
);
}
// Generate a disposable token with write-only access to a single topic in all caches
const oneTopicAllCachesToken = await authClient.generateDisposableToken(
TokenScopes.topicPublishOnly(AllCaches, 'acorn'),
ExpiresIn.minutes(30)
);
switch (oneTopicAllCachesToken.type) {
case GenerateDisposableTokenResponse.Success:
console.log('Generated a disposable API key with access to all topics in the "squirrel" cache!');
// logging only a substring of the tokens, because logging security credentials is not advisable :)
console.log(`API key starts with: ${oneTopicAllCachesToken.authToken.substring(0, 10)}`);
console.log(`Expires At: ${oneTopicAllCachesToken.expiresAt.epoch()}`);
break;
case GenerateDisposableTokenResponse.Error:
throw new Error(
`An error occurred while attempting to call generateApiKey with disposable token scope: ${oneTopicAllCachesToken.errorCode()}: ${oneTopicAllCachesToken.toString()}`
);
}
For more information on Momento tokens, including DisposableTokenScope
and permission objects for authorization, see Auth API Reference.
FAQ
Is the traffic from the browser encrypted?
As with all traffic with Momento services, the web SDK is fully encrypted on the wire. In addition, the SDK uses TLS 1.2+ encryption.