Tasty lil' bytes · RSS | Mastodon

Customize Mastodon to Change Your Post Character Limit

2023-11-27 Please note: My blogging platform has moved to https://1010.gitlab.io and I will post all future updates to this article on the copy of this post at: https://1010.gitlab.io/posts/customize-mastodon-character-limit/

⭐ Updated for Mastodon v4.2.1!

The Mastodon social media service has a 500-character limit on post text. This article documents how you change the character limit in the web user interface and API endpoint that returns instance configuration data to clients (the latter is how many mobile apps that support post length customization define your instance character limit).

These edits must be performed by an instance administrator with access to the server hosting the Mastodon software. This is an instance-wide setting that requires direct edits to the Mastodon software files and applies to all users on an instance. It is not currently possible for users to customize the default value defined on an instance.

I confirmed the instructions below function on my instance as of the Mastodon v4.2.1 release.

Customization Targets

The character limit is defined in two Mastodon source files. We will edit the following JavaScript and Ruby sources:

Note that the JavaScript file extension changed as of the Mastodon v4.2.0 release. The required edits did not.

Documentation of additional instance_serializer.rb file changes for earlier REST API v1 instance endpoint support are available; however, this does not appear to be relevant as of the latest API v1 and API v2 updates (at least as of the changes that landed in this pull request). I can confirm the current versions of the official Mastodon app on iOS and Android, Ivory on iOS, Toot! on iOS, IceCubes on iOS, and Tusky on Android release support the character limit increase approach described here as of the Mastodon v4.2.1 release. Please review the documentation in the link above if you need to support an earlier version of the REST API. And ping the client app development team about the API update if they use an older API version!

Prep

Log in to your Mastodon user

ssh into your server and log in to your Mastodon user. Assuming that you defined the user as mastodon at instance setup, the command is:

$ su - mastodon

(Optional) Create a new git branch for your modifications

Please note: Upstream/downstream git repository management is well beyond the scope of the information presented here. Please look into this issue in more detail if you are unaware of the consequences of your edits and intend to update your instance's Mastodon version in the future.

If you cloned the Mastodon source repository with git as documented in the official instance setup docs, I recommend creating a new git branch for your modifications. This is optional but likely to help you pull new changes from the upstream Mastodon repository main branch to your local upstream tracking branch as new releases are available.

Change to the Mastodon live directory (this is the git repository root) and enter the following command:

$ git checkout -b mods

This generates a local modifications branch named mods starting at your instance’s Mastodon release version git tag commit.

To get back to the main branch that is tracking upstream Mastodon, either git stash or commit the changes that you make based on the documentation below, and then use the following command:

$ git checkout main

You can remove all live edits defined in your mods branch using the instructions below by switching back to the main branch with the command above, checking out a desired Mastodon release tag, recompiling Mastodon, and restarting your Mastodon services. The recompile and service restart commands are documented below.

Source Edits

compose_form.js(x)

Open the compose_form.js (pre-v4.2.0) or compose_form.jsx (post-v4.2.0) JavaScript file with your preferred text editor. Here, I’ll use vim with the source file path as of v4.2.1:

$ vim live/app/javascript/mastodon/features/compose/components/compose_form.jsx

Replace 500 in the following lines (as of Mastodon v4.2.1) with your new limit value:

return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > 500 || (isOnlyWhitespace && !anyMedia));
<CharacterCounter max={500} text={this.getFulltextForCharacterCounting()} />

And write the changes to disk.

status_length_validator.rb

Open the status_length_validator.rb Ruby file with your text editor. Again, I’ll use vim with the source file path:

$ vim live/app/validators/status_length_validator.rb

Replace 500 in the MAX_CHARS definition below (as of Mastodon v4.2.1) with your new limit value:

class StatusLengthValidator < ActiveModel::Validator
   MAX_CHARS = 500
   URL_PLACEHOLDER_CHARS = 23
   URL_PLACEHOLDER = 'x' * 23

And write the changes to disk.

Git Patch

v4.0.x

Here is a git patch with the full set of v4.0.x changes:

diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.js
index 6a65f44da..b1e364451 100644
--- a/app/javascript/mastodon/features/compose/components/compose_form.js
+++ b/app/javascript/mastodon/features/compose/components/compose_form.js
@@ -90,7 +90,7 @@ class ComposeForm extends ImmutablePureComponent {
     const fulltext = this.getFulltextForCharacterCounting();
     const isOnlyWhitespace = fulltext.length !== 0 && fulltext.trim().length === 0;

-    return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > 500 || (isOnlyWhitespace && !anyMedia));
+    return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > 5000 || (isOnlyWhitespace && !anyMedia));
   }

   handleSubmit = (e) => {
@@ -277,7 +277,7 @@ class ComposeForm extends ImmutablePureComponent {
           </div>

           <div className='character-counter__wrapper'>
-            <CharacterCounter max={500} text={this.getFulltextForCharacterCounting()} />
+            <CharacterCounter max={5000} text={this.getFulltextForCharacterCounting()} />
           </div>
         </div>

diff --git a/app/validators/status_length_validator.rb b/app/validators/status_length_validator.rb
index e107912b7..a3cbe5123 100644
--- a/app/validators/status_length_validator.rb
+++ b/app/validators/status_length_validator.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true

 class StatusLengthValidator < ActiveModel::Validator
-  MAX_CHARS = 500
+  MAX_CHARS = 5000
   URL_PLACEHOLDER_CHARS = 23
   URL_PLACEHOLDER = 'x' * 23

v4.1.x

Here is a git patch with the full set of v4.1.x changes:

diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.js
index e641d59f4..9b6f84fa1 100644
--- a/app/javascript/mastodon/features/compose/components/compose_form.js
+++ b/app/javascript/mastodon/features/compose/components/compose_form.js
@@ -90,7 +90,7 @@ class ComposeForm extends ImmutablePureComponent {
     const fulltext = this.getFulltextForCharacterCounting();
     const isOnlyWhitespace = fulltext.length !== 0 && fulltext.trim().length === 0;

-    return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > 500 || (isOnlyWhitespace && !anyMedia));
+    return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > 5000 || (isOnlyWhitespace && !anyMedia));
   };

   handleSubmit = (e) => {
@@ -280,7 +280,7 @@ class ComposeForm extends ImmutablePureComponent {
           </div>

           <div className='character-counter__wrapper'>
-            <CharacterCounter max={500} text={this.getFulltextForCharacterCounting()} />
+            <CharacterCounter max={5000} text={this.getFulltextForCharacterCounting()} />
           </div>
         </div>

diff --git a/app/validators/status_length_validator.rb b/app/validators/status_length_validator.rb
index e107912b7..a3cbe5123 100644
--- a/app/validators/status_length_validator.rb
+++ b/app/validators/status_length_validator.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true

 class StatusLengthValidator < ActiveModel::Validator
-  MAX_CHARS = 500
+  MAX_CHARS = 5000
   URL_PLACEHOLDER_CHARS = 23
   URL_PLACEHOLDER = 'x' * 23

v4.2.x

Here is a git patch with the full set of v4.2.x changes:

diff --git a/app/javascript/mastodon/features/compose/components/compose_form.jsx b/app/javascript/mastodon/features/compose/components/compose_form.jsx
index 9222b2dc8..962310a28 100644
--- a/app/javascript/mastodon/features/compose/components/compose_form.jsx
+++ b/app/javascript/mastodon/features/compose/components/compose_form.jsx
@@ -100,7 +100,7 @@ class ComposeForm extends ImmutablePureComponent {
     const fulltext = this.getFulltextForCharacterCounting();
     const isOnlyWhitespace = fulltext.length !== 0 && fulltext.trim().length === 0;

-    return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > 500 || (isOnlyWhitespace && !anyMedia));
+    return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > 5000 || (isOnlyWhitespace && !anyMedia));
   };

   handleSubmit = (e) => {
@@ -297,7 +297,7 @@ class ComposeForm extends ImmutablePureComponent {
             </div>

             <div className='character-counter__wrapper'>
-              <CharacterCounter max={500} text={this.getFulltextForCharacterCounting()} />
+              <CharacterCounter max={5000} text={this.getFulltextForCharacterCounting()} />
             </div>
           </div>
         </div>
diff --git a/app/validators/status_length_validator.rb b/app/validators/status_length_validator.rb
index dc841ded3..9cb1ec94b 100644
--- a/app/validators/status_length_validator.rb
+++ b/app/validators/status_length_validator.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true

 class StatusLengthValidator < ActiveModel::Validator
-  MAX_CHARS = 500
+  MAX_CHARS = 5000
   URL_PLACEHOLDER_CHARS = 23
   URL_PLACEHOLDER = 'x' * 23

Rebuild Mastodon

Change to the live sub-directory from your mastodon user home directory:

$ cd live

and re-compile your Mastodon project with the following command:

$ RAILS_ENV=production bundle exec rails assets:precompile

Restart Your Mastodon Services

Exit to your root user:

$ exit

and execute the following commands to restart (or reload) your Mastodon services:

$ systemctl restart mastodon-sidekiq
$ systemctl reload mastodon-web

Reload your Mastodon instance in the web browser UI, and you should be ready to post with the new character limit.

Confirm the Mastodon REST API Update

REST API clients will rely on the updated max character count data in your instance API endpoint.

Here is an example of the relevant part of the JSON response from the mastodon.social instance:

"configuration": {
    "urls": {
      "streaming": "wss://mastodon.social"
    },
    "accounts": {
      "max_featured_tags": 10
    },
    "statuses": {
      "max_characters": 500,
      "max_media_attachments": 4,
      "characters_reserved_per_url": 23
    },

By default, the max_characters field is defined with 500 characters.

Your instance's response should be different. Use a GET request to retrieve the JSON data at the following URL:

https://[ENTER YOUR DOMAIN HERE]/api/v2/instance

You should see the following updates in the response:

"configuration": {
    "urls": {
      "streaming": "wss://[YOUR DOMAIN]"
    },
    "accounts": {
      "max_featured_tags": 10
    },
    "statuses": {
      "max_characters": 5000,
      "max_media_attachments": 4,
      "characters_reserved_per_url": 23
    },

max_characters will list the custom character limit value you defined in the steps here if all went well with your patch. You can use this API check to troubleshoot any issues you encounter in clients that support custom character limits.

Close and reload all REST API clients that support custom post lengths to apply the update. This includes Mastodon applications on mobile devices. You should now see the updated character count value in the UI.

UI Update Examples

Here's a selection of client demos with expected UI changes when your max character count changes.

Mastodon Web UI

A screenshot of the Mastodon web UI.  The image demonstrates a new, custom max character limit of 5000.

Mastodon official app on iOS

A screenshot of the Mastodon mobile application on iOS.  The image demonstrates a new, custom max character limit of 5000.

Tusky on Android

A screenshot of the Tusky mobile application on Android.  The image demonstrates a new, custom max character limit of 5000.

Toot! on iOS

A screenshot of the Toot! mobile application on iOS.  The image demonstrates a new, custom max character limit of 5000.

Discuss

Don’t hesitate to reach out if you want to discuss character length limits or this approach to change them. And please let me know if you recognize these instructions have become outdated before I do!

Edits

2023-10-13: updated documentation with the requirements in Mastodon v4.1.x and v4.2.x, including the compose_form.jsx path change as of v4.2.0.

2022-12-22: added a “Git Patch” section with a Mastodon v4.0.2 git patch that describes the source code changes.

#admin #mastodon