1
0
mirror of https://codeberg.org/fediverse/fep.git synced 2026-08-05 03:35:52 +00:00

FEP-9098: Custom emojis (#647)

Reviewed-on: https://codeberg.org/fediverse/fep/pulls/647
Co-authored-by: silverpill <silverpill@firemail.cc>
Co-committed-by: silverpill <silverpill@firemail.cc>
This commit is contained in:
silverpill
2025-07-06 00:04:07 +02:00
committed by silverpill
parent 1f4fe98209
commit 67d713945c
+129
View File
@@ -0,0 +1,129 @@
---
slug: "9098"
authors: silverpill <@silverpill@mitra.social>
type: implementation
status: DRAFT
dateReceived: 2025-07-06
discussionsTo: https://codeberg.org/silverpill/feps/issues
---
# FEP-9098: Custom emojis
## Summary
This document describes how custom emojis are implemented in [ActivityPub] network.
## History
Custom emojis were introduced by Pleroma ([commits](https://gitgud.io/lambadalambda/pleroma/-/compare/c17c8ce36d35db03a007a264cc2e507afa9b803e...7c82b8219734102ff24d9dc24226c08351e608cc)) and Mastodon ([PR](https://github.com/mastodon/mastodon/pull/4988)) in 2017.
## Requirements
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC-2119].
## Emoji object
Custom emojis are represented as `Emoji` objects (the full type IRI is `http://joinmastodon.org/ns#Emoji`). The `Emoji` object has the following properties:
- `id` (RECOMMENDED): the unique identifier of the custom emoji. Some implementations omit this property (i.e. the object is anonymous).
- `type` (REQUIRED): the `Emoji` string.
- `name` (REQUIRED): the [shortcode][Shortcode] of the custom emoji (the name of the emoji, enclosed in colons).
- `updated` (OPTIONAL): the date when custom emoji was updated, formatted as [RFC-3339] timestamp.
- `icon` (REQUIRED): `Image` object describing emoji image.
- `type` (REQUIRED): the `Image` string.
- `url` (REQUIRED): the URL of the emoji image.
Example:
```json
{
"id": "https://social.example/emoji/blobcat",
"type": "Emoji",
"name": ":blobcat:",
"updated": "1970-01-01T00:00:00Z",
"icon": {
"type": "Image",
"url": "https://social.example/media/blobcat.png"
}
}
```
### Uniqueness
The primary unique identifier of a custom emoji is a combination of its name and the domain name. The domain name can be extracted from the `id` of `Emoji` object or from the `id` of the object within which it is embedded.
If `id` is not guaranteed to be globally unique, it MUST be omitted.
### Accessibility
The short description of a custom emoji can be specified with the `alternateName` property (the full IRI is `http://schema.org/alternateName`).
### Compatibility
In order to be compatible with as many servers as possible, implementations SHOULD comply with the following additional requirements:
- Name contains at least two characters ([Mastodon](https://github.com/mastodon/mastodon/blob/v4.3.7/app/models/custom_emoji.rb#L28)).
- Name matches the regular expression `^[a-zA-Z0-9_]+$` ([Mastodon](https://github.com/mastodon/mastodon/blob/v4.3.7/app/models/custom_emoji.rb#L30)).
- Image media type is `image/png`, `image/gif` or `image/webp` ([Mastodon](https://github.com/mastodon/mastodon/blob/v4.3.7/app/models/custom_emoji.rb#L37)).
- Image size is not greater than 256 KB ([Mastodon](https://github.com/mastodon/mastodon/blob/v4.3.7/app/models/custom_emoji.rb#L27)).
- Image is a square (some clients may display non-squre emojis with a wrong aspect ratio).
## Using custom emojis
### Microsyntax
Custom emojis can be inserted into textual representations of an object using [shortcodes][Shortcode] (shortcode is a name of an emoji enclosed in colons: `:emojiname:`). These textual representations are often specified with `name`, `summary` and `content` properties.
The corresponding `Emoji` objects are added to the `tag` array of the object.
Example:
```json
{
"type": "Note",
"content": "<p>:blobcat:</p>",
"tag": [
{
"id": "https://social.example/emoji/blobcat",
"type": "Emoji",
"name": ":blobcat:",
"icon": {
"type": "Image",
"url": "https://social.example/media/blobcat.png"
}
}
]
}
```
### Rendering
Applications typically replace custom emoji shortcodes with `<img>` HTML tags and render the output as HTML.
To prevent [Cross-Site Scripting (XSS)][XSS] attacks, implementers MUST ensure that:
- Emoji names, descriptions, URLs and other strings that are used in replacements do not contain reserved HTML characters.
- When HTML content (e.g. `summary`, `content`) is processed, shortcodes are replaced only inside [Text][DOM-Text] nodes.
- Reserved HTML characters in text are escaped before replacing shortcodes.
## Implementations
This document is based on implementations of custom emojis in Pleroma, Mastodon, Misskey and Fedibird.
## References
- Christine Lemmer-Webber, Jessica Tallon, Erin Shepherd, Amy Guy, Evan Prodromou, [ActivityPub], 2018
- S. Bradner, [Key words for use in RFCs to Indicate Requirement Levels][RFC-2119], 1997
- G. Klyne, C. Newman, [Date and Time on the Internet: Timestamps][RFC-3339], 2002
[ActivityPub]: https://www.w3.org/TR/activitypub/
[RFC-2119]: https://tools.ietf.org/html/rfc2119.html
[RFC-3339]: https://www.rfc-editor.org/rfc/rfc3339
[Shortcode]: https://emojipedia.org/shortcodes
[XSS]: https://owasp.org/www-community/attacks/xss/
[DOM-Text]: https://developer.mozilla.org/en-US/docs/Web/API/Text
## Copyright
CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
To the extent possible under law, the authors of this Fediverse Enhancement Proposal have waived all copyright and related or neighboring rights to this work.