Ivory
Ivory is a Mastodon client by Tapbots. Protocol Launcher allows you to generate Ivory URL scheme links.
Usage
There are two ways to use this library:
- On-Demand import from subpaths enables tree-shaking and keeps bundles small.
- Full Import from the root package is convenient but includes all app modules.
Pick On-Demand for production builds; Full Import is fine for quick scripts or demos.
Select Installation Method
On-Demand
Recommended. Optimized for production.
Full Import
Convenient. Good for quick scripts.
Notes
Tapbots documents acct as the account selector. It can be a fully qualified @user@host, a short @user, or blank for the currently active Ivory account. When acct is omitted, Protocol Launcher generates URLs such as ivory:///home.
This module only exposes the official Ivory URL shapes: tab URLs, openURL, status, user_profile, and post. callbackUrl is only available for the documented modal actions and serializes to the official callback_url query parameter.
Tabs
ts
import { openHome, openTimeline, openMentions, openLists, openFavorites, openBookmarks, openStatistics, openProfileTab, openSearch } from 'protocol-launcher/ivory'
const homeUrl = openHome()
const timelineUrl = openTimeline({ acct: '@alice' })
const mentionsUrl = openMentions({ acct: '@alice' })
const listsUrl = openLists()
const favoritesUrl = openFavorites()
const bookmarksUrl = openBookmarks()
const statisticsUrl = openStatistics()
const profileTabUrl = openProfileTab({ acct: '@alice@mastodon.social' })
const searchUrl = openSearch()Open URL
ts
import { openUrl } from 'protocol-launcher/ivory'
const url = openUrl({
acct: '@alice@mastodon.social',
url: 'https://mastodon.social/@tapbots',
callbackUrl: 'launcher://done',
})Open Status
ts
import { openStatus } from 'protocol-launcher/ivory'
const url = openStatus({
acct: '@alice@mastodon.social',
statusId: '110123456789',
})Open Profile
ts
import { openProfile } from 'protocol-launcher/ivory'
const url = openProfile({
acct: '@alice@mastodon.social',
userAcct: '@tapbots@mastodon.social',
})Compose
ts
import { compose } from 'protocol-launcher/ivory'
const url = compose({
acct: '@alice',
callbackUrl: 'launcher://done',
})Compose Text Path
ts
import { composeText } from 'protocol-launcher/ivory'
const url = composeText({
acct: '@alice',
text: 'Hello Ivory',
})Compose Reply
ts
import { composeReply } from 'protocol-launcher/ivory'
const url = composeReply({
acct: '@alice',
text: 'Hello Ivory',
inReplyToStatusUrl: 'https://mastodon.social/@tapbots/110123456789',
})Generated URLs
ts
openHome()
// => 'ivory:///home'
openTimeline({ acct: '@alice' })
// => 'ivory://@alice/timeline'
openUrl({
acct: '@alice@mastodon.social',
url: 'https://mastodon.social/@tapbots',
callbackUrl: 'launcher://done',
})
// => 'ivory://@alice@mastodon.social/openURL?url=https%3A%2F%2Fmastodon.social%2F%40tapbots&callback_url=launcher%3A%2F%2Fdone'
openStatus({
acct: '@alice@mastodon.social',
statusId: '110123456789',
})
// => 'ivory://@alice@mastodon.social/status/110123456789'
openProfile({
acct: '@alice@mastodon.social',
userAcct: '@tapbots@mastodon.social',
})
// => 'ivory://@alice@mastodon.social/user_profile/@tapbots@mastodon.social'
compose()
// => 'ivory:///post'
compose({
acct: '@alice',
callbackUrl: 'launcher://done',
})
// => 'ivory://@alice/post?callback_url=launcher%3A%2F%2Fdone'
composeText({
acct: '@alice',
text: 'Hello Ivory',
})
// => 'ivory://@alice/post/Hello%20Ivory'
composeReply({
acct: '@alice',
text: 'Hello Ivory',
inReplyToStatusUrl: 'https://mastodon.social/@tapbots/110123456789',
})
// => 'ivory://@alice/post?text=Hello%20Ivory&in_reply_to_status_url=https%3A%2F%2Fmastodon.social%2F%40tapbots%2F110123456789'