diff --git a/app/controllers/settings/preferences_controller.rb b/app/controllers/settings/preferences_controller.rb
index d548072a8014885b5cbc1521b7b62cca64173851..edf29947bb046761c86ce3f9b7453aecea30a719 100644
--- a/app/controllers/settings/preferences_controller.rb
+++ b/app/controllers/settings/preferences_controller.rb
@@ -56,6 +56,7 @@ class Settings::PreferencesController < Settings::BaseController
       :setting_advanced_layout,
       :setting_use_blurhash,
       :setting_use_pending_items,
+      :setting_trends,
       notification_emails: %i(follow follow_request reblog favourite mention digest report pending_account trending_tag),
       interactions: %i(must_be_follower must_be_following must_be_following_dm)
     )
diff --git a/app/javascript/mastodon/actions/trends.js b/app/javascript/mastodon/actions/trends.js
new file mode 100644
index 0000000000000000000000000000000000000000..853e4f60aec711f0d3437163fa3e8a680e0869cb
--- /dev/null
+++ b/app/javascript/mastodon/actions/trends.js
@@ -0,0 +1,32 @@
+import api from '../api';
+
+export const TRENDS_FETCH_REQUEST = 'TRENDS_FETCH_REQUEST';
+export const TRENDS_FETCH_SUCCESS = 'TRENDS_FETCH_SUCCESS';
+export const TRENDS_FETCH_FAIL    = 'TRENDS_FETCH_FAIL';
+
+export const fetchTrends = () => (dispatch, getState) => {
+  dispatch(fetchTrendsRequest());
+
+  api(getState)
+    .get('/api/v1/trends')
+    .then(({ data }) => dispatch(fetchTrendsSuccess(data)))
+    .catch(err => dispatch(fetchTrendsFail(err)));
+};
+
+export const fetchTrendsRequest = () => ({
+  type: TRENDS_FETCH_REQUEST,
+  skipLoading: true,
+});
+
+export const fetchTrendsSuccess = trends => ({
+  type: TRENDS_FETCH_SUCCESS,
+  trends,
+  skipLoading: true,
+});
+
+export const fetchTrendsFail = error => ({
+  type: TRENDS_FETCH_FAIL,
+  error,
+  skipLoading: true,
+  skipAlert: true,
+});
diff --git a/app/javascript/mastodon/features/getting_started/components/trends.js b/app/javascript/mastodon/features/getting_started/components/trends.js
new file mode 100644
index 0000000000000000000000000000000000000000..1dcacc8b392351bee55b62f4838178a757a4d706
--- /dev/null
+++ b/app/javascript/mastodon/features/getting_started/components/trends.js
@@ -0,0 +1,43 @@
+import React from 'react';
+import ImmutablePureComponent from 'react-immutable-pure-component';
+import PropTypes from 'prop-types';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import Hashtag from 'mastodon/components/hashtag';
+
+export default class Trends extends ImmutablePureComponent {
+
+  static defaultProps = {
+    loading: false,
+  };
+
+  static propTypes = {
+    trends: ImmutablePropTypes.list,
+    fetchTrends: PropTypes.func.isRequired,
+  };
+
+  componentDidMount () {
+    this.props.fetchTrends();
+    this.refreshInterval = setInterval(() => this.props.fetchTrends(), 36000);
+  }
+
+  componentWillUnmount () {
+    if (this.refreshInterval) {
+      clearInterval(this.refreshInterval);
+    }
+  }
+
+  render () {
+    const { trends } = this.props;
+
+    if (!trends || trends.isEmpty()) {
+      return null;
+    }
+
+    return (
+      <div className='getting-started__trends'>
+        {trends.take(3).map(hashtag => <Hashtag key={hashtag.get('name')} hashtag={hashtag} />)}
+      </div>
+    );
+  }
+
+}
diff --git a/app/javascript/mastodon/features/getting_started/containers/trends_container.js b/app/javascript/mastodon/features/getting_started/containers/trends_container.js
new file mode 100644
index 0000000000000000000000000000000000000000..1df3fb4fe20d616b412e228f345d039f0bbbf410
--- /dev/null
+++ b/app/javascript/mastodon/features/getting_started/containers/trends_container.js
@@ -0,0 +1,13 @@
+import { connect } from 'react-redux';
+import { fetchTrends } from '../../../actions/trends';
+import Trends from '../components/trends';
+
+const mapStateToProps = state => ({
+  trends: state.getIn(['trends', 'items']),
+});
+
+const mapDispatchToProps = dispatch => ({
+  fetchTrends: () => dispatch(fetchTrends()),
+});
+
+export default connect(mapStateToProps, mapDispatchToProps)(Trends);
diff --git a/app/javascript/mastodon/features/getting_started/index.js b/app/javascript/mastodon/features/getting_started/index.js
index 791f22d47140968e33657bbdff5df15f5e8c9735..6a122a750b1aef0844d990026eee3c3a9e61678d 100644
--- a/app/javascript/mastodon/features/getting_started/index.js
+++ b/app/javascript/mastodon/features/getting_started/index.js
@@ -7,12 +7,13 @@ import { connect } from 'react-redux';
 import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import ImmutablePureComponent from 'react-immutable-pure-component';
-import { me, profile_directory } from '../../initial_state';
+import { me, profile_directory, showTrends } from '../../initial_state';
 import { fetchFollowRequests } from 'mastodon/actions/accounts';
 import { List as ImmutableList } from 'immutable';
 import NavigationBar from '../compose/components/navigation_bar';
 import Icon from 'mastodon/components/icon';
 import LinkFooter from 'mastodon/features/ui/components/link_footer';
+import TrendsContainer from './containers/trends_container';
 
 const messages = defineMessages({
   home_timeline: { id: 'tabs_bar.home', defaultMessage: 'Home' },
@@ -168,6 +169,8 @@ class GettingStarted extends ImmutablePureComponent {
 
           <LinkFooter withHotkeys={multiColumn} />
         </div>
+
+        {multiColumn && showTrends && <TrendsContainer />}
       </Column>
     );
   }
diff --git a/app/javascript/mastodon/features/ui/components/navigation_panel.js b/app/javascript/mastodon/features/ui/components/navigation_panel.js
index ef3ad2e092f86e07936985041471a08906620e03..64a40a9da841e5d9a7db38874edb6cf7f04549c6 100644
--- a/app/javascript/mastodon/features/ui/components/navigation_panel.js
+++ b/app/javascript/mastodon/features/ui/components/navigation_panel.js
@@ -2,10 +2,11 @@ import React from 'react';
 import { NavLink, withRouter } from 'react-router-dom';
 import { FormattedMessage } from 'react-intl';
 import Icon from 'mastodon/components/icon';
-import { profile_directory } from 'mastodon/initial_state';
+import { profile_directory, showTrends } from 'mastodon/initial_state';
 import NotificationsCounterIcon from './notifications_counter_icon';
 import FollowRequestsNavLink from './follow_requests_nav_link';
 import ListPanel from './list_panel';
+import TrendsContainer from 'mastodon/features/getting_started/containers/trends_container';
 
 const NavigationPanel = () => (
   <div className='navigation-panel'>
@@ -25,6 +26,9 @@ const NavigationPanel = () => (
     <a className='column-link column-link--transparent' href='/settings/preferences'><Icon className='column-link__icon' id='cog' fixedWidth /><FormattedMessage id='navigation_bar.preferences' defaultMessage='Preferences' /></a>
     <a className='column-link column-link--transparent' href='/relationships'><Icon className='column-link__icon' id='users' fixedWidth /><FormattedMessage id='navigation_bar.follows_and_followers' defaultMessage='Follows and followers' /></a>
     {!!profile_directory && <a className='column-link column-link--transparent' href='/explore'><Icon className='column-link__icon' id='address-book-o' fixedWidth /><FormattedMessage id='navigation_bar.profile_directory' defaultMessage='Profile directory' /></a>}
+
+    {showTrends && <div className='flex-spacer' />}
+    {showTrends && <TrendsContainer />}
   </div>
 );
 
diff --git a/app/javascript/mastodon/initial_state.js b/app/javascript/mastodon/initial_state.js
index cb2ccc7c410cad7a141f85b20b3bb1037596f108..38e7b0595adb8609a64a3a01c5d2e642f6049f38 100644
--- a/app/javascript/mastodon/initial_state.js
+++ b/app/javascript/mastodon/initial_state.js
@@ -22,5 +22,6 @@ export const isStaff = getMeta('is_staff');
 export const forceSingleColumn = !getMeta('advanced_layout');
 export const useBlurhash = getMeta('use_blurhash');
 export const usePendingItems = getMeta('use_pending_items');
+export const showTrends = getMeta('trends');
 
 export default initialState;
diff --git a/app/javascript/mastodon/reducers/index.js b/app/javascript/mastodon/reducers/index.js
index 981ad8e64cfd682bfe94eba5c5504464a34fb639..3b60878eb79aa4e534cb0f59ebc6b0b3f133252e 100644
--- a/app/javascript/mastodon/reducers/index.js
+++ b/app/javascript/mastodon/reducers/index.js
@@ -31,6 +31,7 @@ import conversations from './conversations';
 import suggestions from './suggestions';
 import polls from './polls';
 import identity_proofs from './identity_proofs';
+import trends from './trends';
 
 const reducers = {
   dropdown_menu,
@@ -65,6 +66,7 @@ const reducers = {
   conversations,
   suggestions,
   polls,
+  trends,
 };
 
 export default combineReducers(reducers);
diff --git a/app/javascript/mastodon/reducers/settings.js b/app/javascript/mastodon/reducers/settings.js
index 033bfc999a0f0d224c88bac679a91afd9c10ebcc..793a99f8f56f6beb069e2c2aad0f4766fe994b9d 100644
--- a/app/javascript/mastodon/reducers/settings.js
+++ b/app/javascript/mastodon/reducers/settings.js
@@ -12,6 +12,10 @@ const initialState = ImmutableMap({
 
   skinTone: 1,
 
+  trends: ImmutableMap({
+    show: true,
+  }),
+
   home: ImmutableMap({
     shows: ImmutableMap({
       reblog: true,
diff --git a/app/javascript/mastodon/reducers/trends.js b/app/javascript/mastodon/reducers/trends.js
new file mode 100644
index 0000000000000000000000000000000000000000..5cecc8fcab5f777423edcb9b3d0f9920ac792301
--- /dev/null
+++ b/app/javascript/mastodon/reducers/trends.js
@@ -0,0 +1,23 @@
+import { TRENDS_FETCH_REQUEST, TRENDS_FETCH_SUCCESS, TRENDS_FETCH_FAIL } from '../actions/trends';
+import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';
+
+const initialState = ImmutableMap({
+  items: ImmutableList(),
+  isLoading: false,
+});
+
+export default function trendsReducer(state = initialState, action) {
+  switch(action.type) {
+  case TRENDS_FETCH_REQUEST:
+    return state.set('isLoading', true);
+  case TRENDS_FETCH_SUCCESS:
+    return state.withMutations(map => {
+      map.set('items', fromJS(action.trends));
+      map.set('isLoading', false);
+    });
+  case TRENDS_FETCH_FAIL:
+    return state.set('isLoading', false);
+  default:
+    return state;
+  }
+};
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index f02458ded8452e87df014911981d07ebf158fd50..8de72d72ee7c58008fdd0c19c36f62b7c606d26b 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -2212,7 +2212,6 @@ a.account__display-name {
   }
 
   .getting-started__wrapper,
-  .getting-started__trends,
   .search {
     margin-bottom: 10px;
   }
@@ -2319,13 +2318,24 @@ a.account__display-name {
   margin-bottom: 10px;
   height: calc(100% - 20px);
   overflow-y: auto;
+  display: flex;
+  flex-direction: column;
+
+  & > a {
+    flex: 0 0 auto;
+  }
 
   hr {
+    flex: 0 0 auto;
     border: 0;
     background: transparent;
     border-top: 1px solid lighten($ui-base-color, 4%);
     margin: 10px 0;
   }
+
+  .flex-spacer {
+    background: transparent;
+  }
 }
 
 .drawer__pager {
@@ -2717,8 +2727,10 @@ a.account__display-name {
   }
 
   &__trends {
-    background: $ui-base-color;
     flex: 0 1 auto;
+    opacity: 1;
+    animation: fade 150ms linear;
+    margin-top: 10px;
 
     @media screen and (max-height: 810px) {
       .trends__item:nth-child(3) {
@@ -2735,11 +2747,15 @@ a.account__display-name {
     @media screen and (max-height: 670px) {
       display: none;
     }
-  }
 
-  &__scrollable {
-    max-height: 100%;
-    overflow-y: auto;
+    .trends__item {
+      border-bottom: 0;
+      padding: 10px;
+
+      &__current {
+        color: $darker-text-color;
+      }
+    }
   }
 }
 
@@ -5968,7 +5984,8 @@ noscript {
       font-size: 24px;
       line-height: 36px;
       font-weight: 500;
-      text-align: center;
+      text-align: right;
+      padding-right: 15px;
       color: $secondary-text-color;
     }
 
@@ -5976,7 +5993,12 @@ noscript {
       flex: 0 0 auto;
       width: 50px;
 
-      path {
+      path:first-child {
+        fill: rgba($highlight-text-color, 0.25) !important;
+        fill-opacity: 1 !important;
+      }
+
+      path:last-child {
         stroke: lighten($highlight-text-color, 6%) !important;
       }
     }
diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb
index 9ae9986c282d03568ae96e74edfe240ce53a29b8..3568a3e1167a20bbf03357c57a4d0cd6a359f535 100644
--- a/app/lib/user_settings_decorator.rb
+++ b/app/lib/user_settings_decorator.rb
@@ -36,6 +36,7 @@ class UserSettingsDecorator
     user.settings['advanced_layout']     = advanced_layout_preference if change?('setting_advanced_layout')
     user.settings['use_blurhash']        = use_blurhash_preference if change?('setting_use_blurhash')
     user.settings['use_pending_items']   = use_pending_items_preference if change?('setting_use_pending_items')
+    user.settings['trends']              = trends_preference if change?('setting_trends')
   end
 
   def merged_notification_emails
@@ -122,6 +123,10 @@ class UserSettingsDecorator
     boolean_cast_setting 'setting_use_pending_items'
   end
 
+  def trends_preference
+    boolean_cast_setting 'setting_trends'
+  end
+
   def boolean_cast_setting(key)
     ActiveModel::Type::Boolean.new.cast(settings[key])
   end
diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb
index 2c03c88a8cf16488ec15e0905f6eecb9c967b1d3..051268375e6858a6211d04f7a6da8f94cbfedd5f 100644
--- a/app/models/form/admin_settings.rb
+++ b/app/models/form/admin_settings.rb
@@ -29,6 +29,7 @@ class Form::AdminSettings
     hero
     mascot
     spam_check_enabled
+    trends
   ).freeze
 
   BOOLEAN_KEYS = %i(
@@ -41,6 +42,7 @@ class Form::AdminSettings
     preview_sensitive_media
     profile_directory
     spam_check_enabled
+    trends
   ).freeze
 
   UPLOAD_KEYS = %i(
diff --git a/app/models/trending_tags.rb b/app/models/trending_tags.rb
index e9b9b25e31fa451aae7268789fde7f85b92b5c20..0a7e2feac4e53ca1032500358c88078e08928491 100644
--- a/app/models/trending_tags.rb
+++ b/app/models/trending_tags.rb
@@ -66,6 +66,10 @@ class TrendingTags
     end
 
     def request_review!(tag)
+      return unless Setting.trends
+
+      tag.touch(:requested_review_at)
+
       User.staff.includes(:account).find_each { |u| AdminMailer.new_trending_tag(u.account, tag).deliver_later! if u.allows_trending_tag_emails? }
     end
   end
diff --git a/app/models/user.rb b/app/models/user.rb
index b83e26af3f0a42adcbd64ee86ff4e5382d93f502..a4a20d97512707f070910d48dd718c96eb2fb96f 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -107,7 +107,8 @@ class User < ApplicationRecord
   delegate :auto_play_gif, :default_sensitive, :unfollow_modal, :boost_modal, :delete_modal,
            :reduce_motion, :system_font_ui, :noindex, :theme, :display_media, :hide_network,
            :expand_spoilers, :default_language, :aggregate_reblogs, :show_application,
-           :advanced_layout, :use_blurhash, :use_pending_items, to: :settings, prefix: :setting, allow_nil: false
+           :advanced_layout, :use_blurhash, :use_pending_items, :trends,
+           to: :settings, prefix: :setting, allow_nil: false
 
   attr_reader :invite_code
   attr_writer :external
diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb
index 7e5d3eda90ec8d17f422fff3f75c5325f4b088df..c92c5e606b6953dcc0ca1af91298b88e65d7b7ab 100644
--- a/app/serializers/initial_state_serializer.rb
+++ b/app/serializers/initial_state_serializer.rb
@@ -20,6 +20,7 @@ class InitialStateSerializer < ActiveModel::Serializer
       invites_enabled: Setting.min_invite_role == 'user',
       mascot: instance_presenter.mascot&.file&.url,
       profile_directory: Setting.profile_directory,
+      trends: Setting.trends,
     }
 
     if object.current_account
@@ -35,6 +36,7 @@ class InitialStateSerializer < ActiveModel::Serializer
       store[:use_blurhash]      = object.current_account.user.setting_use_blurhash
       store[:use_pending_items] = object.current_account.user.setting_use_pending_items
       store[:is_staff]          = object.current_account.user.staff?
+      store[:trends]            = Setting.trends && object.current_account.user.setting_trends
     end
 
     store
diff --git a/app/views/admin/settings/edit.html.haml b/app/views/admin/settings/edit.html.haml
index 1e2ed3f77f21c271eef5107f7a7561358a846aea..28c0ece15be677f5f4a6db4bca17b99376e3bd87 100644
--- a/app/views/admin/settings/edit.html.haml
+++ b/app/views/admin/settings/edit.html.haml
@@ -68,6 +68,9 @@
     .fields-group
       = f.input :profile_directory, as: :boolean, wrapper: :with_label, label: t('admin.settings.profile_directory.title'), hint: t('admin.settings.profile_directory.desc_html')
 
+    .fields-group
+      = f.input :trends, as: :boolean, wrapper: :with_label, label: t('admin.settings.trends.title'), hint: t('admin.settings.trends.desc_html')
+
   .fields-group
     = f.input :spam_check_enabled, as: :boolean, wrapper: :with_label, label: t('admin.settings.spam_check_enabled.title'), hint: t('admin.settings.spam_check_enabled.desc_html')
 
diff --git a/app/views/settings/preferences/appearance/show.html.haml b/app/views/settings/preferences/appearance/show.html.haml
index e279a61c4815f36248c62e9724fa0a4c89d8184c..d6ee1933f86dbefcfaf96b35c8f86de725d18c45 100644
--- a/app/views/settings/preferences/appearance/show.html.haml
+++ b/app/views/settings/preferences/appearance/show.html.haml
@@ -25,6 +25,11 @@
     = f.input :setting_reduce_motion, as: :boolean, wrapper: :with_label
     = f.input :setting_system_font_ui, as: :boolean, wrapper: :with_label
 
+  %h4= t 'appearance.discovery'
+
+  .fields-group
+    = f.input :setting_trends, as: :boolean, wrapper: :with_label
+
   %h4= t 'appearance.confirmation_dialogs'
 
   .fields-group
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 9b62aac3af34c353facb652c51ec15ac5ed42cf8..67c392662855922381f55d79d1b67d467f4fb236 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -460,8 +460,8 @@ en:
         title: Custom terms of service
       site_title: Server name
       spam_check_enabled:
-        desc_html: Mastodon can auto-silence and auto-report accounts based on measures such as detecting accounts who send repeated unsolicited messages. There may be false positives.
-        title: Anti-spam
+        desc_html: Mastodon can auto-silence and auto-report accounts that send repeated unsolicited messages. There may be false positives.
+        title: Anti-spam automation
       thumbnail:
         desc_html: Used for previews via OpenGraph and API. 1200x630px recommended
         title: Server thumbnail
@@ -469,6 +469,9 @@ en:
         desc_html: Display public timeline on landing page
         title: Timeline preview
       title: Site settings
+      trends:
+        desc_html: Publicly display previously reviewed hashtags that are currently trending
+        title: Trending hashtags
     statuses:
       back_to_account: Back to account page
       batch:
@@ -514,6 +517,7 @@ en:
     advanced_web_interface_hint: 'If you want to make use of your entire screen width, the advanced web interface allows you to configure many different columns to see as much information at the same time as you want: Home, notifications, federated timeline, any number of lists and hashtags.'
     animations_and_accessibility: Animations and accessibility
     confirmation_dialogs: Confirmation dialogs
+    discovery: Discovery
     sensitive_content: Sensitive content
   application_mailer:
     notification_preferences: Change e-mail preferences
diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml
index 6fdfc9d7bce5f9ae7534784b1d3af85c40a161c8..e15d5904fd7aa012f9f14cd4856fd24596042785 100644
--- a/config/locales/simple_form.en.yml
+++ b/config/locales/simple_form.en.yml
@@ -114,6 +114,7 @@ en:
         setting_show_application: Disclose application used to send toots
         setting_system_font_ui: Use system's default font
         setting_theme: Site theme
+        setting_trends: Show today's trends
         setting_unfollow_modal: Show confirmation dialog before unfollowing someone
         setting_use_blurhash: Show colorful gradients for hidden media
         setting_use_pending_items: Slow mode
diff --git a/config/settings.yml b/config/settings.yml
index 10180201f323df3313eda8e8e1bcde4ccb8ac607..4e5eefb5934d34bdfd1a925f0b5ac2b0990013bf 100644
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -34,6 +34,7 @@ defaults: &defaults
   advanced_layout: false
   use_blurhash: true
   use_pending_items: false
+  trends: true
   notification_emails:
     follow: false
     reblog: false