# Message formatting
Zulip supports an extended version of Markdown for messages, as well as
some HTML level special behavior. The Zulip help center article on [message
formatting](/help/format-your-message-using-markdown) is the primary
documentation for Zulip's markup features. This article is currently a
changelog for updates to these features.
The [render a message](/api/render-message) endpoint can be used to get
the current HTML version of any Markdown syntax for message content.
## Code blocks
**Changes**: As of Zulip 4.0 (feature level 33), [code blocks][help-code]
can have a `data-code-language` attribute attached to the outer HTML
`div` element, which records the programming language that was selected
for syntax highlighting. This field is used in the
[playgrounds][help-playgrounds] feature for code blocks.
## Global times
**Changes**: In Zulip 3.0 (feature level 8), added [global time
mentions][help-global-time] to supported Markdown message formatting
features.
## Links to channels, topics, and messages
Zulip's markup supports special readable Markdown syntax for [linking
to channels, topics, and messages](/help/link-to-a-message-or-conversation).
Sample HTML formats are as follows:
``` html
#announce
#announce > Zulip updates
#announce > Zulip updates
#announce > Zulip updates @ 💬
```
The `near` and `with` operators are documented in more detail in the
[search and URL documentation](/api/construct-narrow). When rendering
topic links with the `with` operator, the code doing the rendering may
pick the ID arbitrarily among messages accessible to the client and/or
acting user at the time of rendering. Currently, the server chooses
the message ID to use for `with` operators as the latest message ID in
the topic accessible to the user who wrote the message.
The older stream/topic link elements include a `data-stream-id`, which
historically was used in order to display the current channel name if
the channel had been renamed. That field is **deprecated**, because
displaying an updated value for the most common forms of this syntax
requires parsing the URL to get the topic to use anyway.
When a topic is an empty string, it is replaced with
`realm_empty_topic_display_name` found in the [`POST /register`](/api/register-queue)
response and wrapped with the `` tag.
Sample HTML formats with `"realm_empty_topic_display_name": "general chat"`
are as follows:
```html
#announce > general chat
#announce > general chat
#announce > general chat @ 💬
```
**Changes**: In Zulip 11.0 (feature level 400), the server switched
its strategy for `with` URL construction to choose the latest
accessible message ID in a topic. Previously, it used the oldest.
Before Zulip 10.0 (feature level 347), the `with` field
was never used in topic link URLs generated by the server; the markup
currently used only for empty topics was used for all topic links.
Before Zulip 10.0 (feature level 346), empty string
was not a valid topic name in syntaxes for linking to topics and
messages.
In Zulip 10.0 (feature level 319), added Markdown syntax
for linking to a specific message in a conversation. Declared the
`data-stream-id` field to be deprecated as detailed above.
In Zulip 11.0 (feature level 383), clients can decide what
channel view a.stream channel link elements take you to -- i.e.,
the href for those is the default behavior of the link that also
encodes the channel alongside the data-stream-id field, but clients
can override that default based on `web_channel_default_view` setting.
## Image previews
When a Zulip message is sent linking to an uploaded image, Zulip will
generate an image preview element with the following format.
``` html
```
If the server has not yet generated thumbnails for the image yet at
the time the message is sent, the `img` element will be a temporary
loading indicator image and have the `image-loading-placeholder`
class, which clients can use to identify loading indicators and
replace them with a more native loading indicator element if
desired. For example:
``` html
```
Once the server has a working thumbnail, such messages will be updated
via an `update_message` event, with the `rendering_only: true` flag
(telling clients not to adjust message edit history), with appropriate
adjusted `rendered_content`. A client should process those events by
just using the updated rendering. If thumbnailing failed, the same
type of event will edit the message's rendered form to remove the
image preview element, so no special client-side logic should be
required to process such errors.
Note that in the uncommon situation that the thumbnailing system is
backlogged, an individual message containing multiple image previews
may be re-rendered multiple times as each image finishes thumbnailing
and triggers a message update.
Clients are recommended to do the following when processing image
previews:
- Clients that would like to use the image's aspect ratio to lay out
one or more images in the message feed may use the
`data-original-dimensions` attribute, which is present even if the
image is a placeholder spinner. This attribute encodes the
dimensions of the original image as `{width}x{height}`. These
dimensions are for the image as rendered, _after_ any EXIF rotation
and mirroring has been applied.
- If the client would like to control the thumbnail resolution used,
it can replace the final section of the URL (`840x560.webp` in the
example above) with the `name` of its preferred format from the set
of supported formats provided by the server in the
`server_thumbnail_formats` portion of the `register`
response. Clients should not make any assumptions about what format
the server will use as the "default" thumbnail resolution, as it may
change over time.
- Download button type elements should provide the original image
(encoded via the `href` of the containing `a` tag).
- The content-type of the original image is provided on a
`data-original-content-type` attribute, so clients can decide if
they are capable of rendering the original image.
- For images whose formats which are not widely-accepted by browsers
(e.g., HEIC and TIFF), the image may contain a
`data-transcoded-image` attribute, which specifies a high-resolution
thumbnail format which clients may use instead of the original
image.
- Lightbox elements for viewing an image should be designed to
immediately display any already-downloaded thumbnail while fetching
the original-quality image or an appropriate higher-quality
thumbnail from the server, to be transparently swapped in once it is
available. Clients that would like to size the lightbox based on the
size of the original image can use the `data-original-dimensions`
attribute, as described above.
- Animated images will have a `data-animated` attribute on the `img`
tag. As detailed in `server_thumbnail_formats`, both animated and
still images are available for clients to use, depending on their
preference. See, for example, the [web setting][help-previews]
to control whether animated images are autoplayed in the message
feed.
- Clients should not assume that the requested format is the format
that they will receive; in rare cases where the client has an
out-of-date list of `server_thumbnail_formats`, the server will
provide an approximation of the client's requested format. Because
of this, clients should not assume that the pixel dimensions or file
format match what they requested.
- No other processing of the URLs is recommended.
**Changes**: In Zulip 10.0 (feature level 336), added
`data-original-content-type` attribute to convey the type of the
original image, and optional `data-transcoded-image` attribute for
images with formats which are not widely supported by browsers.
**Changes**: In Zulip 9.2 (feature levels 278-279, and 287+), added
`data-original-dimensions` to the `image-loading-placeholder` spinner
images, containing the dimensions of the original image.
In Zulip 9.0 (feature level 276), added `data-original-dimensions`
attribute to images that have been thumbnailed, containing the
dimensions of the full-size version of the image. Thumbnailing itself
was reintroduced at feature level 275.
Previously, with the exception of Zulip servers that used the beta
Thumbor-based implementation years ago, all image previews in Zulip
messages were not thumbnailed; the `a` tag and the `img` tag would both
point to the original image.
Clients that correctly implement the current API should handle
Thumbor-based older thumbnails correctly, as long as they do not
assume that `data-original-dimensions` is present. Clients should not
assume that messages sent prior to the introduction of thumbnailing
have been re-rendered to use the new format or have thumbnails
available.
## Video embeddings and previews
When a Zulip message is sent linking to an uploaded video, Zulip may
generate a video preview element with the following format.
``` html
```
## Audio Players
When the Markdown media syntax is used with an uploaded file with an
audio `Content-Type`, Zulip will generate an HTML5 `