diff --git a/.env.production.sample b/.env.production.sample
index 326c2cc409..b604c4b04d 100644
--- a/.env.production.sample
+++ b/.env.production.sample
@@ -270,7 +270,7 @@ MAX_POLL_OPTIONS=5
 MAX_POLL_OPTION_CHARS=100
 
 # Maximum number of emoji reactions per toot and user (minimum 1)
-MAX_REACTIONS=8
+MAX_REACTIONS=1
 
 # Maximum image and video/audio upload sizes
 # Units are in bytes
diff --git a/app/javascript/flavours/glitch/components/status.jsx b/app/javascript/flavours/glitch/components/status.jsx
index 5e612499ac..323e9f5a8a 100644
--- a/app/javascript/flavours/glitch/components/status.jsx
+++ b/app/javascript/flavours/glitch/components/status.jsx
@@ -840,6 +840,7 @@ class Status extends ImmutablePureComponent {
           <StatusReactions
             statusId={status.get('id')}
             reactions={status.get('reactions')}
+            numVisible={settings.get('num_visible_reactions')}
             addReaction={this.props.onReactionAdd}
             removeReaction={this.props.onReactionRemove}
             emojiMap={this.props.emojiMap}
diff --git a/app/javascript/flavours/glitch/components/status_reactions.js b/app/javascript/flavours/glitch/components/status_reactions.js
index cc85a0189a..39956270a4 100644
--- a/app/javascript/flavours/glitch/components/status_reactions.js
+++ b/app/javascript/flavours/glitch/components/status_reactions.js
@@ -1,7 +1,7 @@
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
-import { maxReactions, reduceMotion } from '../initial_state';
+import { reduceMotion } from '../initial_state';
 import spring from 'react-motion/lib/spring';
 import TransitionMotion from 'react-motion/lib/TransitionMotion';
 import classNames from 'classnames';
@@ -16,16 +16,12 @@ export default class StatusReactions extends ImmutablePureComponent {
   static propTypes = {
     statusId: PropTypes.string.isRequired,
     reactions: ImmutablePropTypes.list.isRequired,
+    numVisible: PropTypes.number,
     addReaction: PropTypes.func.isRequired,
     removeReaction: PropTypes.func.isRequired,
     emojiMap: ImmutablePropTypes.map.isRequired,
   };
 
-  handleEmojiPick = data => {
-    const { addReaction, statusId } = this.props;
-    addReaction(statusId, data.native.replace(/:/g, ''));
-  }
-
   willEnter() {
     return { scale: reduceMotion ? 1 : 0 };
   }
@@ -35,11 +31,18 @@ export default class StatusReactions extends ImmutablePureComponent {
   }
 
   render() {
-    const { reactions } = this.props;
-    const visibleReactions = reactions
+    const { reactions, numVisible } = this.props;
+    let visibleReactions = reactions
       .filter(x => x.get('count') > 0)
-      .sort((a, b) => b.get('count') - a.get('count'))
-      .filter((_, i) => i < maxReactions);
+      .sort((a, b) => b.get('count') - a.get('count'));
+
+    // numVisible might be NaN because it's pulled from local settings
+    // which doesn't do a whole lot of input validation, but that's okay
+    // because  NaN >= 0  evaluates false.
+    // Still, this should be improved at some point.
+    if (numVisible >= 0) {
+      visibleReactions = visibleReactions.filter((_, i) => i < numVisible);
+    }
 
     const styles = visibleReactions.map(reaction => ({
       key: reaction.get('name'),
diff --git a/app/javascript/flavours/glitch/features/local_settings/page/index.jsx b/app/javascript/flavours/glitch/features/local_settings/page/index.jsx
index 929391927f..6db085f974 100644
--- a/app/javascript/flavours/glitch/features/local_settings/page/index.jsx
+++ b/app/javascript/flavours/glitch/features/local_settings/page/index.jsx
@@ -37,6 +37,8 @@ const messages = defineMessages({
   unlisted: { id: 'privacy.unlisted.short', defaultMessage: 'Unlisted' },
   private: { id: 'privacy.private.short', defaultMessage: 'Followers only' },
   direct: { id: 'privacy.direct.short', defaultMessage: 'Mentioned people only' },
+  visible_reactions_count: { id: 'settings.visible_reactions_count', defaultMessage: 'Number of visible reactions' },
+  enter_amount_prompt: { id: 'settings.enter_amount_prompt', defaultMessage: 'Enter an amount' },
 });
 
 class LocalSettingsPage extends PureComponent {
@@ -99,6 +101,16 @@ class LocalSettingsPage extends PureComponent {
         >
           <FormattedMessage id='settings.rewrite_mentions' defaultMessage='Rewrite mentions in displayed statuses' />
         </LocalSettingsPageItem>
+        <LocalSettingsPageItem
+          settings={settings}
+          item={['num_visible_reactions']}
+          id='mastodon-settings--num_visible_reactions'
+          onChange={onChange}
+          placeholder={intl.formatMessage(messages.enter_amount_prompt)}
+          number
+        >
+          <FormattedMessage id='settings.num_visible_reactions' defaultMessage='Number of visible reaction badges:' />
+        </LocalSettingsPageItem>
         <section>
           <h2><FormattedMessage id='settings.notifications_opts' defaultMessage='Notifications options' /></h2>
           <LocalSettingsPageItem
diff --git a/app/javascript/flavours/glitch/features/local_settings/page/item/index.jsx b/app/javascript/flavours/glitch/features/local_settings/page/item/index.jsx
index 15dce634d2..ff755654e7 100644
--- a/app/javascript/flavours/glitch/features/local_settings/page/item/index.jsx
+++ b/app/javascript/flavours/glitch/features/local_settings/page/item/index.jsx
@@ -22,20 +22,21 @@ export default class LocalSettingsPageItem extends PureComponent {
     })),
     settings: ImmutablePropTypes.map.isRequired,
     placeholder: PropTypes.string,
+    number: PropTypes.bool,
     disabled: PropTypes.bool,
   };
 
   handleChange = e => {
     const { target } = e;
-    const { item, onChange, options, placeholder } = this.props;
+    const { item, onChange, options, placeholder, number } = this.props;
     if (options && options.length > 0) onChange(item, target.value);
-    else if (placeholder) onChange(item, target.value);
+    else if (placeholder) onChange(item, number ? parseInt(target.value) : target.value);
     else onChange(item, target.checked);
   };
 
   render () {
     const { handleChange } = this;
-    const { settings, item, id, inputProps, options, children, dependsOn, dependsOnNot, placeholder, disabled } = this.props;
+    const { settings, item, id, inputProps, options, children, dependsOn, dependsOnNot, placeholder, number, disabled } = this.props;
     let enabled = !disabled;
 
     if (dependsOn) {
@@ -79,7 +80,7 @@ export default class LocalSettingsPageItem extends PureComponent {
           </fieldset>
         </div>
       );
-    } else if (placeholder) {
+    } else if (placeholder || number) {
       return (
         <div className='glitch local-settings__page__item string'>
           <label htmlFor={id}>
@@ -87,7 +88,7 @@ export default class LocalSettingsPageItem extends PureComponent {
             <p>
               <input
                 id={id}
-                type='text'
+                type={number ? 'number' : 'text'}
                 value={settings.getIn(item)}
                 placeholder={placeholder}
                 onChange={handleChange}
diff --git a/app/javascript/flavours/glitch/locales/de.js b/app/javascript/flavours/glitch/locales/de.js
new file mode 100644
index 0000000000..18eb398d84
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/de.js
@@ -0,0 +1,15 @@
+import inherited from 'mastodon/locales/de.json';
+
+const messages = {
+  'notification.reaction': '{name} hat auf deinen Beitrag reagiert',
+  'notifications.column_settings.reaction': 'Reaktionen:',
+
+  'tooltips.reactions': 'Reaktionen',
+
+  'settings.enter_amount_prompt': 'Gib eine Zahl ein',
+  'settings.num_visible_reactions': 'Anzahl sichtbarer Reaktionen',
+
+  'status.react': 'Reagieren',
+};
+
+export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/de.json b/app/javascript/flavours/glitch/locales/de.json
index 6a081c34d6..91d452c786 100644
--- a/app/javascript/flavours/glitch/locales/de.json
+++ b/app/javascript/flavours/glitch/locales/de.json
@@ -136,6 +136,7 @@
   "settings.deprecated_setting": "Diese Einstellung wird nun von Mastodons {settings_page_link} gesteuert",
   "settings.enable_collapsed": "Eingeklappte Toots aktivieren",
   "settings.enable_collapsed_hint": "Eingeklappte Posts haben einen Teil ihres Inhalts verborgen, um weniger Platz am Bildschirm einzunehmen. Das passiert unabhängig von der Inhaltswarnfunktion",
+  "settings.enter_amount_prompt": "Gib eine Zahl ein",
   "settings.enable_content_warnings_auto_unfold": "Inhaltswarnungen automatisch ausklappen",
   "settings.general": "Allgemein",
   "settings.hicolor_privacy_icons": "Eingefärbte Privatsphäre-Symbole",
@@ -149,6 +150,7 @@
   "settings.layout_opts": "Layout-Optionen",
   "settings.media": "Medien",
   "settings.media_fullwidth": "Medienvorschau in voller Breite",
+  "settings.num_visible_reactions": "Anzahl sichtbarer Reaktionen",
   "settings.media_letterbox": "Mediengröße anpassen",
   "settings.media_letterbox_hint": "Medien runterskalieren und einpassen um die Bildbehälter zu füllen anstatt zu strecken und zuzuschneiden",
   "settings.media_reveal_behind_cw": "Empfindliche Medien hinter Inhaltswarnungen standardmäßig anzeigen",
@@ -191,6 +193,7 @@
   "settings.wide_view": "Breite Ansicht (nur für den Desktop-Modus)",
   "settings.wide_view_hint": "Verbreitert Spalten, um den verfügbaren Platz besser zu füllen.",
   "status.collapse": "Einklappen",
+  "status.react": "Reagieren",
   "status.has_audio": "Hat angehängte Audiodateien",
   "status.has_pictures": "Hat angehängte Bilder",
   "status.has_preview_card": "Hat eine Vorschaukarte",
diff --git a/app/javascript/flavours/glitch/locales/en.js b/app/javascript/flavours/glitch/locales/en.js
new file mode 100644
index 0000000000..54a4c2940c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/en.js
@@ -0,0 +1,199 @@
+import inherited from 'mastodon/locales/en.json';
+
+const messages = {
+  'getting_started.open_source_notice': 'Glitchsoc is free open source software forked from {Mastodon}. You can contribute or report issues on GitHub at {github}.',
+  'layout.auto': 'Auto',
+  'layout.current_is': 'Your current layout is:',
+  'layout.desktop': 'Desktop',
+  'layout.single': 'Mobile',
+  'layout.hint.auto': 'Automatically chose layout based on “Enable advanced web interface” setting and screen size.',
+  'layout.hint.desktop': 'Use multiple-column layout regardless of the “Enable advanced web interface” setting or screen size.',
+  'layout.hint.single': 'Use single-column layout regardless of the “Enable advanced web interface” setting or screen size.',
+  'navigation_bar.app_settings': 'App settings',
+  'navigation_bar.misc': 'Misc',
+  'navigation_bar.keyboard_shortcuts': 'Keyboard shortcuts',
+  'navigation_bar.info': 'Extended information',
+  'navigation_bar.featured_users': 'Featured users',
+  'getting_started.onboarding': 'Show me around',
+  'onboarding.next': 'Next',
+  'onboarding.done': 'Done',
+  'onboarding.skip': 'Skip',
+  'onboarding.page_one.federation': '{domain} is an \'instance\' of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.',
+  'onboarding.page_one.welcome': 'Welcome to {domain}!',
+  'onboarding.page_one.handle': 'You are on {domain}, so your full handle is {handle}',
+  'onboarding.page_two.compose': 'Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.',
+  'onboarding.page_three.search': 'Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.',
+  'onboarding.page_three.profile': 'Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.',
+  'onboarding.page_four.home': 'The home timeline shows posts from people you follow.',
+  'onboarding.page_four.notifications': 'The notifications column shows when someone interacts with you.',
+  'onboarding.page_five.public_timelines': 'The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.',
+  'onboarding.page_six.admin': 'Your instance\'s admin is {admin}.',
+  'onboarding.page_six.read_guidelines': 'Please read {domain}\'s {guidelines}!',
+  'onboarding.page_six.guidelines': 'community guidelines',
+  'onboarding.page_six.almost_done': 'Almost done...',
+  'onboarding.page_six.github': '{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}, and is compatible with any Mastodon instance or app. Glitchsoc is entirely free and open-source. You can report bugs, request features, or contribute to the code on {github}.',
+  'onboarding.page_six.apps_available': 'There are {apps} available for iOS, Android and other platforms.',
+  'onboarding.page_six.various_app': 'mobile apps',
+  'onboarding.page_six.appetoot': 'Bon Appetoot!',
+  'settings.auto_collapse': 'Automatic collapsing',
+  'settings.auto_collapse_all': 'Everything',
+  'settings.auto_collapse_lengthy': 'Lengthy toots',
+  'settings.auto_collapse_media': 'Toots with media',
+  'settings.auto_collapse_notifications': 'Notifications',
+  'settings.auto_collapse_reblogs': 'Boosts',
+  'settings.auto_collapse_replies': 'Replies',
+  'settings.show_action_bar': 'Show action buttons in collapsed toots',
+  'settings.close': 'Close',
+  'settings.collapsed_statuses': 'Collapsed toots',
+  'settings.enable_collapsed': 'Enable collapsed toots',
+  'settings.enable_collapsed_hint': 'Collapsed posts have parts of their contents hidden to take up less screen space. This is distinct from the Content Warning feature',
+  'settings.enter_amount_prompt': 'Enter an amount',
+  'settings.general': 'General',
+  'settings.compose_box_opts': 'Compose box',
+  'settings.side_arm': 'Secondary toot button:',
+  'settings.side_arm.none': 'None',
+  'settings.side_arm_reply_mode': 'When replying to a toot, the secondary toot button should:',
+  'settings.side_arm_reply_mode.keep': 'Keep its set privacy',
+  'settings.side_arm_reply_mode.copy': 'Copy privacy setting of the toot being replied to',
+  'settings.side_arm_reply_mode.restrict': 'Restrict privacy setting to that of the toot being replied to',
+  'settings.always_show_spoilers_field': 'Always enable the Content Warning field',
+  'settings.prepend_cw_re': 'Prepend “re: ” to content warnings when replying',
+  'settings.preselect_on_reply': 'Pre-select usernames on reply',
+  'settings.preselect_on_reply_hint': 'When replying to a conversation with multiple participants, pre-select usernames past the first',
+  'settings.confirm_missing_media_description': 'Show confirmation dialog before sending toots lacking media descriptions',
+  'settings.confirm_before_clearing_draft': 'Show confirmation dialog before overwriting the message being composed',
+  'settings.show_content_type_choice': 'Show content-type choice when authoring toots',
+  'settings.content_warnings': 'Content Warnings',
+  'settings.content_warnings.regexp': 'Regular expression',
+  'settings.content_warnings_shared_state': 'Show/hide content of all copies at once',
+  'settings.content_warnings_shared_state_hint': 'Reproduce upstream Mastodon behavior by having the Content Warning button affect all copies of a post at once. This will prevent automatic collapsing of any copy of a toot with unfolded CW',
+  'settings.content_warnings_media_outside': 'Display media attachments outside content warnings',
+  'settings.content_warnings_media_outside_hint': 'Reproduce upstream Mastodon behavior by having the Content Warning toggle not affect media attachments',
+  'settings.content_warnings_unfold_opts': 'Auto-unfolding options',
+  'settings.enable_content_warnings_auto_unfold': 'Automatically unfold content-warnings',
+  'settings.deprecated_setting': 'This setting is now controlled from Mastodon\'s {settings_page_link}',
+  'settings.shared_settings_link': 'user preferences',
+  'settings.content_warnings_filter': 'Content warnings to not automatically unfold:',
+  'settings.layout_opts': 'Layout options',
+  'settings.rewrite_mentions_no': 'Do not rewrite mentions',
+  'settings.rewrite_mentions_acct': 'Rewrite with username and domain (when the account is remote)',
+  'settings.rewrite_mentions_username': 'Rewrite with username',
+  'settings.show_reply_counter': 'Display an estimate of the reply count',
+  'settings.hicolor_privacy_icons': 'High color privacy icons',
+  'settings.hicolor_privacy_icons.hint': 'Display privacy icons in bright and easily distinguishable colors',
+  'settings.confirm_boost_missing_media_description': 'Show confirmation dialog before boosting toots lacking media descriptions',
+  'settings.tag_misleading_links': 'Tag misleading links',
+  'settings.tag_misleading_links.hint': 'Add a visual indication with the link target host to every link not mentioning it explicitly',
+  'settings.rewrite_mentions': 'Rewrite mentions in displayed statuses',
+  'settings.notifications_opts': 'Notifications options',
+  'settings.notifications.tab_badge': 'Unread notifications badge',
+  'settings.notifications.tab_badge.hint': 'Display a badge for unread notifications in the column icons when the notifications column isn\'t open',
+  'settings.notifications.favicon_badge': 'Unread notifications favicon badge',
+  'settings.notifications.favicon_badge.hint': 'Add a badge for unread notifications to the favicon',
+  'settings.status_icons': 'Toot icons',
+  'settings.status_icons_language': 'Language indicator',
+  'settings.status_icons_reply': 'Reply indicator',
+  'settings.status_icons_local_only': 'Local-only indicator',
+  'settings.status_icons_media': 'Media and poll indicators',
+  'settings.status_icons_visibility': 'Toot privacy indicator',
+  'settings.layout': 'Layout:',
+  'settings.image_backgrounds': 'Image backgrounds',
+  'settings.image_backgrounds_media': 'Preview collapsed toot media',
+  'settings.image_backgrounds_media_hint': 'If the post has any media attachment, use the first one as a background',
+  'settings.image_backgrounds_users': 'Give collapsed toots an image background',
+  'settings.media': 'Media',
+  'settings.media_letterbox': 'Letterbox media',
+  'settings.media_letterbox_hint': 'Scale down and letterbox media to fill the image containers instead of stretching and cropping them',
+  'settings.media_fullwidth': 'Full-width media previews',
+  'settings.num_visible_reactions': 'Number of visible reactions',
+  'settings.inline_preview_cards': 'Inline preview cards for external links',
+  'settings.media_reveal_behind_cw': 'Reveal sensitive media behind a CW by default',
+  'settings.pop_in_player': 'Enable pop-in player',
+  'settings.pop_in_position': 'Pop-in player position:',
+  'settings.pop_in_left': 'Left',
+  'settings.pop_in_right': 'Right',
+  'settings.preferences': 'User preferences',
+  'settings.wide_view': 'Wide view (Desktop mode only)',
+  'settings.wide_view_hint': 'Stretches columns to better fill the available space.',
+  'settings.navbar_under': 'Navbar at the bottom (Mobile only)',
+  'status.collapse': 'Collapse',
+  'status.react': 'React',
+  'status.uncollapse': 'Uncollapse',
+  'status.in_reply_to': 'This toot is a reply',
+  'status.has_preview_card': 'Features an attached preview card',
+  'status.has_pictures': 'Features attached pictures',
+  'status.is_poll': 'This toot is a poll',
+  'status.has_video': 'Features attached videos',
+  'status.has_audio': 'Features attached audio files',
+  'status.local_only': 'Only visible from your instance',
+
+  'content_type.change': 'Content type',
+  'compose.content-type.html': 'HTML',
+  'compose.content-type.markdown': 'Markdown',
+  'compose.content-type.plain': 'Plain text',
+
+  'compose_form.poll.single_choice': 'Allow one choice',
+  'compose_form.poll.multiple_choices': 'Allow multiple choices',
+  'compose_form.spoiler': 'Hide text behind warning',
+
+  'column.toot': 'Toots and replies',
+  'column_header.profile': 'Profile',
+  'column.heading': 'Misc',
+  'column.subheading': 'Miscellaneous options',
+  'column_subheading.navigation': 'Navigation',
+  'column_subheading.lists': 'Lists',
+
+  'media_gallery.sensitive': 'Sensitive',
+
+  'favourite_modal.combo': 'You can press {combo} to skip this next time',
+
+  'home.column_settings.show_direct': 'Show DMs',
+
+  'notification.markForDeletion': 'Mark for deletion',
+  'notification.reaction': '{name} reacted to your post',
+  'notifications.clear': 'Clear all my notifications',
+  'notifications.column_settings.reaction': 'Reactions:',
+  'notifications.marked_clear_confirmation': 'Are you sure you want to permanently clear all selected notifications?',
+  'notifications.marked_clear': 'Clear selected notifications',
+
+  'notification_purge.start': 'Enter notification cleaning mode',
+  'notification_purge.btn_all': 'Select\nall',
+  'notification_purge.btn_none': 'Select\nnone',
+  'notification_purge.btn_invert': 'Invert\nselection',
+  'notification_purge.btn_apply': 'Clear\nselected',
+
+  'compose.attach.upload': 'Upload a file',
+  'compose.attach.doodle': 'Draw something',
+  'compose.attach': 'Attach...',
+
+  'advanced_options.local-only.short': 'Local-only',
+  'advanced_options.local-only.long': 'Do not post to other instances',
+  'advanced_options.local-only.tooltip': 'This post is local-only',
+  'advanced_options.icon_title': 'Advanced options',
+  'advanced_options.threaded_mode.short': 'Threaded mode',
+  'advanced_options.threaded_mode.long': 'Automatically opens a reply on posting',
+  'advanced_options.threaded_mode.tooltip': 'Threaded mode enabled',
+
+  'endorsed_accounts_editor.endorsed_accounts': 'Featured accounts',
+
+  'account.add_account_note': 'Add note for @{name}',
+  'account_note.cancel': 'Cancel',
+  'account_note.save': 'Save',
+  'account_note.edit': 'Edit',
+  'account_note.glitch_placeholder': 'No comment provided',
+  'account.joined': 'Joined {date}',
+  'account.follows': 'Follows',
+
+  'home.column_settings.advanced': 'Advanced',
+  'home.column_settings.filter_regex': 'Filter out by regular expressions',
+  'direct.group_by_conversations': 'Group by conversation',
+  'community.column_settings.allow_local_only': 'Show local-only toots',
+
+  'keyboard_shortcuts.bookmark': 'to bookmark',
+  'keyboard_shortcuts.toggle_collapse': 'to collapse/uncollapse toots',
+  'keyboard_shortcuts.secondary_toot': 'to send toot using secondary privacy setting',
+
+  'tooltips.reactions': 'Reactions',
+};
+
+export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/en.json b/app/javascript/flavours/glitch/locales/en.json
index 64947c75d2..b4005d8057 100644
--- a/app/javascript/flavours/glitch/locales/en.json
+++ b/app/javascript/flavours/glitch/locales/en.json
@@ -139,6 +139,7 @@
   "settings.deprecated_setting": "This setting is now controlled from Mastodon's {settings_page_link}",
   "settings.enable_collapsed": "Enable collapsed toots",
   "settings.enable_collapsed_hint": "Collapsed posts have parts of their contents hidden to take up less screen space. This is distinct from the Content Warning feature",
+  "settings.enter_amount_prompt": "Enter an amount",
   "settings.enable_content_warnings_auto_unfold": "Automatically unfold content-warnings",
   "settings.general": "General",
   "settings.hicolor_privacy_icons": "High color privacy icons",
@@ -152,6 +153,7 @@
   "settings.layout_opts": "Layout options",
   "settings.media": "Media",
   "settings.media_fullwidth": "Full-width media previews",
+  "settings.num_visible_reactions": "Number of visible reactions",
   "settings.media_letterbox": "Letterbox media",
   "settings.media_letterbox_hint": "Scale down and letterbox media to fill the image containers instead of stretching and cropping them",
   "settings.media_reveal_behind_cw": "Reveal sensitive media behind a CW by default",
@@ -194,6 +196,7 @@
   "settings.wide_view": "Wide view (Desktop mode only)",
   "settings.wide_view_hint": "Stretches columns to better fill the available space.",
   "status.collapse": "Collapse",
+  "status.react": "React",
   "status.has_audio": "Features attached audio files",
   "status.has_pictures": "Features attached pictures",
   "status.has_preview_card": "Features an attached preview card",
diff --git a/app/javascript/flavours/glitch/locales/fr.js b/app/javascript/flavours/glitch/locales/fr.js
new file mode 100644
index 0000000000..802c71896e
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/fr.js
@@ -0,0 +1,15 @@
+import inherited from 'mastodon/locales/fr.json';
+
+const messages = {
+  'notification.reaction': '{name} a réagi·e à votre message',
+  'notifications.column_settings.reaction': 'Réactions:',
+
+  'tooltips.reactions': 'Réactions',
+
+  'settings.enter_amount_prompt': 'Entrez un montant',
+  'settings.num_visible_reactions': 'Nombre de réactions visibles',
+
+  'status.react': 'Réagir',
+};
+
+export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/fr.json b/app/javascript/flavours/glitch/locales/fr.json
index 107928ac8d..589012d6fc 100644
--- a/app/javascript/flavours/glitch/locales/fr.json
+++ b/app/javascript/flavours/glitch/locales/fr.json
@@ -129,6 +129,7 @@
   "settings.deprecated_setting": "Cette option est maintenant définie par les {settings_page_link} de Mastodon",
   "settings.enable_collapsed": "Activer le repliement des posts",
   "settings.enable_collapsed_hint": "Les posts repliés ont une partie de leur contenu caché pour libérer de l'espace sur l'écran. C'est une option différente de l'avertissement de contenu",
+  "settings.enter_amount_prompt": "Entrez un montant",
   "settings.enable_content_warnings_auto_unfold": "Déplier automatiquement les avertissements de contenu",
   "settings.general": "Général",
   "settings.hicolor_privacy_icons": "Indicateurs de confidentialité en couleurs",
@@ -142,6 +143,7 @@
   "settings.layout_opts": "Mise en page",
   "settings.media": "Média",
   "settings.media_fullwidth": "Utiliser toute la largeur pour les aperçus",
+  "settings.num_visible_reactions": "Nombre de réactions visibles",
   "settings.media_letterbox": "Afficher les médias en Letterbox",
   "settings.media_letterbox_hint": "Réduit le média et utilise une letterbox pour afficher l'image entière plutôt que de l'étirer et de la rogner",
   "settings.media_reveal_behind_cw": "Toujours afficher les médias sensibles avec avertissement",
@@ -192,6 +194,7 @@
   "status.is_poll": "Ce post est un sondage",
   "status.local_only": "Visible uniquement depuis votre instance",
   "status.sensitive_toggle": "Cliquer pour voir",
+  "status.react": "Réagir",
   "status.uncollapse": "Déplier",
   "web_app_crash.change_your_settings": "Changez vos {settings}",
   "web_app_crash.content": "Voici les différentes options qui s'offrent à vous :",
diff --git a/app/javascript/flavours/glitch/reducers/local_settings.js b/app/javascript/flavours/glitch/reducers/local_settings.js
index 21e9dcec2c..05935c2a83 100644
--- a/app/javascript/flavours/glitch/reducers/local_settings.js
+++ b/app/javascript/flavours/glitch/reducers/local_settings.js
@@ -22,6 +22,7 @@ const initialState = ImmutableMap({
   show_content_type_choice: false,
   tag_misleading_links: true,
   rewrite_mentions: 'no',
+  num_visible_reactions: 6,
   content_warnings : ImmutableMap({
     filter       : null,
     media_outside: false,