Creating Your First Presence
Create a new Nowly presence with the CLI and send your first Discord Rich Presence activity.
Start With the CLI
Use the Nowly CLI to scaffold a new presence:
nowly init "Example"CLI 1.7.0+ creates metadata, a presence script, settings.ts, locales, and an assets directory. Define options in the default export of settings.ts; see Settings. Inline definitions remain supported as a legacy format.
Basic Presence Code
Presence and Assets are provided by the runtime - see Presence API and Assets.
document is the standard browser DOM API, available because presences run as content scripts in the extension.
Only PresenceType (and other helpers like createMediaTimestamps) must be imported from @nowly/sdk.
import { PresenceType } from "@nowly/sdk"
const presence = new Presence()
presence.on("UpdateData", async () => {
await presence.setActivity({
details: document.title,
state: document.location.hostname,
largeImageKey: Assets.Logo,
type: PresenceType.Watching,
})
})Runtime Flow
When the user visits a matching URL, Nowly loads your presence. The presence reads page state and calls setActivity. The extension forwards that payload to Nowly Host, which updates Discord.
Development Loop
Scaffold
Generate the presence folder, metadata, and required assets.
nowly init "Example"Scaffold
Generate the presence folder, metadata, and required assets.
nowly init "Example"Configure
Set the name, author, supported URLs, category, color, localized descriptions, and discordNative when Discord already supports the platform.
Edit metadata.json - see Metadata for all available fields.
Configure
Set the name, author, supported URLs, category, color, localized descriptions, and discordNative when Discord already supports the platform.
Edit metadata.json - see Metadata for all available fields.
Implement
Write the presence logic using the Presence SDK.
import { PresenceType } from "@nowly/sdk"
const presence = new Presence()
presence.on("UpdateData", async () => {
await presence.setActivity({
details: document.title,
largeImageKey: Assets.Logo,
type: PresenceType.Watching,
})
})Implement
Write the presence logic using the Presence SDK.
import { PresenceType } from "@nowly/sdk"
const presence = new Presence()
presence.on("UpdateData", async () => {
await presence.setActivity({
details: document.title,
largeImageKey: Assets.Logo,
type: PresenceType.Watching,
})
})Validate
Check that your metadata structure is correct and assets are in place.
nowly validateValidate
Check that your metadata structure is correct and assets are in place.
nowly validateBuild
Compile the presence into a standalone bundle.
nowly build exampleBuild
Compile the presence into a standalone bundle.
nowly build exampleLoad
Install the built presence in the browser. Two methods: a pre-built extension, or a zip drop.
See Load and Test Locally for the full comparison.
First time (no Nowly in the browser): bake the presence into a ready-made extension.
nowly extension example # Chrome (default)
nowly extension example --firefoxLoad dist/extension-dev unpacked at chrome://extensions for Chrome. For Firefox, open about:debugging#/runtime/this-firefox and load dist/extension-dev-firefox/manifest.json with Load Temporary Add-on.
Already have Nowly loaded unpacked: pack a zip and drop it in Settings → Advanced → Debug. Store installs reject unsigned zips.
nowly pack exampleLoad
Install the built presence in the browser. Two methods: a pre-built extension, or a zip drop.
See Load and Test Locally for the full comparison.
First time (no Nowly in the browser): bake the presence into a ready-made extension.
nowly extension example # Chrome (default)
nowly extension example --firefoxLoad dist/extension-dev unpacked at chrome://extensions for Chrome. For Firefox, open about:debugging#/runtime/this-firefox and load dist/extension-dev-firefox/manifest.json with Load Temporary Add-on.
Already have Nowly loaded unpacked: pack a zip and drop it in Settings → Advanced → Debug. Store installs reject unsigned zips.
nowly pack exampleTest
Open the target website - the presence activates automatically.
Visit the site
Test
Open the target website - the presence activates automatically.
Visit the site
Repeat Implement → Build → Load after each code change.