diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0420db5b..643dfcd4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 - Implemented user option to change sidebar position to the right side
 - Implemented user option to hide floating shout panel
 - Implemented "edit profile" button if viewing own profile which opens profile settings
+- Implemented user option to always show floating New Post button (normally mobile-only)
 
 ### Fixed
 - Fixed follow request count showing in the wrong location in mobile view
diff --git a/src/App.js b/src/App.js
index 362ac19d..f5e0b9e9 100644
--- a/src/App.js
+++ b/src/App.js
@@ -73,6 +73,9 @@ export default {
         this.$store.state.instance.instanceSpecificPanelContent
     },
     showFeaturesPanel () { return this.$store.state.instance.showFeaturesPanel },
+    shoutboxPosition () {
+      return this.$store.getters.mergedConfig.showNewPostButton || false
+    },
     hideShoutbox () {
       return this.$store.getters.mergedConfig.hideShoutbox
     },
diff --git a/src/App.vue b/src/App.vue
index c30f5e98..eb65b548 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -53,6 +53,7 @@
       v-if="currentUser && shout && !hideShoutbox"
       :floating="true"
       class="floating-shout mobile-hidden"
+      :class="{ 'left': shoutboxPosition }"
     />
     <MobilePostStatusButton />
     <UserReportingModal />
diff --git a/src/components/mobile_post_status_button/mobile_post_status_button.js b/src/components/mobile_post_status_button/mobile_post_status_button.js
index 366ea89c..d27fb3b8 100644
--- a/src/components/mobile_post_status_button/mobile_post_status_button.js
+++ b/src/components/mobile_post_status_button/mobile_post_status_button.js
@@ -44,6 +44,9 @@ const MobilePostStatusButton = {
 
       return this.autohideFloatingPostButton && (this.hidden || this.inputActive)
     },
+    isPersistent () {
+      return !!this.$store.getters.mergedConfig.showNewPostButton
+    },
     autohideFloatingPostButton () {
       return !!this.$store.getters.mergedConfig.autohideFloatingPostButton
     }
diff --git a/src/components/mobile_post_status_button/mobile_post_status_button.vue b/src/components/mobile_post_status_button/mobile_post_status_button.vue
index 767f8244..37becf4c 100644
--- a/src/components/mobile_post_status_button/mobile_post_status_button.vue
+++ b/src/components/mobile_post_status_button/mobile_post_status_button.vue
@@ -2,7 +2,7 @@
   <div v-if="isLoggedIn">
     <button
       class="button-default new-status-button"
-      :class="{ 'hidden': isHidden }"
+      :class="{ 'hidden': isHidden, 'always-show': isPersistent }"
       @click="openPostForm"
     >
       <FAIcon icon="pen" />
@@ -47,7 +47,7 @@
 }
 
 @media all and (min-width: 801px) {
-  .new-status-button {
+  .new-status-button:not(.always-show) {
     display: none;
   }
 }
diff --git a/src/components/settings_modal/tabs/general_tab.vue b/src/components/settings_modal/tabs/general_tab.vue
index d3e71b31..f2ec7d64 100644
--- a/src/components/settings_modal/tabs/general_tab.vue
+++ b/src/components/settings_modal/tabs/general_tab.vue
@@ -122,6 +122,11 @@
             {{ $t('settings.sensitive_by_default') }}
           </BooleanSetting>
         </li>
+        <li>
+          <BooleanSetting path="alwaysShowNewPostButton">
+            {{ $t('settings.always_show_post_button') }}
+          </BooleanSetting>
+        </li>
         <li>
           <BooleanSetting path="autohideFloatingPostButton">
             {{ $t('settings.autohide_floating_post_button') }}
diff --git a/src/components/shout_panel/shout_panel.vue b/src/components/shout_panel/shout_panel.vue
index f90baf80..c88797d1 100644
--- a/src/components/shout_panel/shout_panel.vue
+++ b/src/components/shout_panel/shout_panel.vue
@@ -79,12 +79,19 @@
 
 .floating-shout {
   position: fixed;
-  right: 0px;
   bottom: 0px;
   z-index: 1000;
   max-width: 25em;
 }
 
+.floating-shout.left {
+  left: 0px;
+}
+
+.floating-shout:not(.left) {
+  right: 0px;
+}
+
 .shout-panel {
   .shout-heading {
     cursor: pointer;
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 018d3b7d..6afc9ecb 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -352,6 +352,7 @@
     "hide_isp": "Hide instance-specific panel",
     "hide_shoutbox": "Hide instance shoutbox",
     "right_sidebar": "Show sidebar on the right side",
+    "always_show_post_button": "Always show floating New Post button",
     "hide_wallpaper": "Hide instance wallpaper",
     "preload_images": "Preload images",
     "use_one_click_nsfw": "Open NSFW attachments with just one click",
diff --git a/src/modules/config.js b/src/modules/config.js
index 33e2cb50..bc3db11b 100644
--- a/src/modules/config.js
+++ b/src/modules/config.js
@@ -35,6 +35,7 @@ export const defaultState = {
   loopVideoSilentOnly: true,
   streaming: false,
   emojiReactionsOnTimeline: true,
+  alwaysShowNewPostButton: false,
   autohideFloatingPostButton: false,
   pauseOnUnfocused: true,
   stopGifs: false,