Index: plugins/plugin-directory/class-plugin-directory.php
===================================================================
--- plugins/plugin-directory/class-plugin-directory.php	(revision 6074)
+++ plugins/plugin-directory/class-plugin-directory.php	(working copy)
@@ -46,6 +46,7 @@
 		add_action( 'wp_head', array( Template::class, 'json_ld_schema' ), 1 );
 		add_action( 'wp_head', array( Template::class, 'meta_description' ), 1 );
 		add_action( 'wp_head', array( Template::class, 'hreflang_link_attributes' ), 2 );
+		add_action( 'wp_head', array( Template::class, 'output_meta' ), 1 );
 
 		// Cron tasks.
 		new Jobs\Manager();
@@ -317,7 +318,7 @@
 		) );
 		register_post_status( 'disabled', array(
 			'label'                     => _x( 'Disabled', 'plugin status', 'wporg-plugins' ),
-			'public'                    => false,
+			'public'                    => true,
 			'show_in_admin_status_list' => current_user_can( 'plugin_disable' ),
 			'label_count'               => _n_noop( 'Disabled <span class="count">(%s)</span>', 'Disabled <span class="count">(%s)</span>', 'wporg-plugins' ),
 		) );
@@ -818,6 +819,13 @@
 			}, 10, 2 );
 		}
 
+		// Allow anyone to view a disabled plugin directly from its page. It won't show in search results or lists.
+		if ( !empty( $wp_query->query_vars['name'] ) ) {
+			$wp_query->query_vars['post_status'] = (array) $wp_query->query_vars['post_status'];
+			$wp_query->query_vars['post_status'][] = 'disabled';
+			$wp_query->query_vars['post_status'] = array_unique( $wp_query->query_vars['post_status'] );
+		}
+
 		// By default, all archives are sorted by active installs
 		if ( $wp_query->is_archive() && empty( $wp_query->query_vars['orderby'] ) ) {
 			$wp_query->query_vars['orderby']  = 'meta_value_num';
Index: plugins/plugin-directory/class-template.php
===================================================================
--- plugins/plugin-directory/class-template.php	(revision 6074)
+++ plugins/plugin-directory/class-template.php	(working copy)
@@ -45,16 +45,24 @@
 		endif;
 
 		// Schema for plugin pages.
-		if ( is_singular( 'plugin' ) ) :
-			$plugin = get_queried_object();
+		if ( is_singular( 'plugin' ) && get_post_status( get_queried_object_id() ) !== 'disabled' ) {
+			self::plugin_json_jd_schema( get_queried_object() );
+		}
+	}
 
-			$rating      = get_post_meta( $plugin->ID, 'rating', true ) ?: 0;
-			$ratings     = get_post_meta( $plugin->ID, 'ratings', true ) ?: [];
-			$num_ratings = array_sum( $ratings );
+	/**
+	 * Prints JSON LD schema for a specific plugin
+	 *
+	 * @param \WP_Post $plugin Plugin to output JSON LD Schema for.
+	 */
+	protected static function plugin_json_jd_schema( $plugin ) {
+		$rating      = get_post_meta( $plugin->ID, 'rating', true ) ?: 0;
+		$ratings     = get_post_meta( $plugin->ID, 'ratings', true ) ?: [];
+		$num_ratings = array_sum( $ratings );
 
-			echo PHP_EOL;
-			?>
-<script type="application/ld+json">
+		echo PHP_EOL;
+		?>
+		<script type="application/ld+json">
 	[
 		{
 			"@context": "http://schema.org",
@@ -114,11 +122,24 @@
 		}
 	]
 </script>
-			<?php
-		endif;
+		<?php
 	}
 
 	/**
+	 * Prints meta tags on a page.
+	 */
+	public static function output_meta() {
+		$metas = [];
+
+		// Add noindex on disabled plugin page.
+		if ( is_singular( 'plugin' ) && get_post_status( get_queried_object_id() ) === 'disabled' ) {
+			$metas[] = '<meta name="robots" content="noindex" />';
+		}
+
+		echo implode( PHP_EOL, $metas );
+	}
+
+	/**
 	 * Prints meta description in the head of a page.
 	 *
 	 * @static
Index: themes/pub/wporg-plugins/template-parts/plugin-single.php
===================================================================
--- themes/pub/wporg-plugins/template-parts/plugin-single.php	(revision 6074)
+++ themes/pub/wporg-plugins/template-parts/plugin-single.php	(working copy)
@@ -24,7 +24,7 @@
 				<p><?php _e( 'This plugin <strong>hasn&#146;t been updated in over 2 years</strong>. It may no longer be maintained or supported and may have compatibility issues when used with more recent versions of WordPress.', 'wporg-plugins' ); ?></p>
 			</div><!-- .plugin-notice -->
 		<?php endif; ?>
-		<?php if ( 'publish' != get_post()->post_status ) :
+<?php if ( 'publish' != get_post()->post_status ) :
 				$notice_type = 'notice-error';
 				switch ( get_post()->post_status ) {
 					case 'draft':
@@ -50,7 +50,7 @@
 						// fall through
 					default:
 					case 'closed':
-						$message = __( 'This plugin is closed and is not visible to the public.', 'wporg-plugins' );
+						$message = __( 'This plugin is closed and no longer available for download.', 'wporg-plugins' );
 						break;
 				}
 			?>
@@ -95,7 +95,9 @@
 				</div>
 			<?php endif; ?>
 
+			<?php if ( get_post_status() !== 'disabled' || current_user_can( 'plugin_admin_view', get_post() ) ) : ?>
 			<a class="plugin-download button download-button button-large" href="<?php echo esc_url( Template::download_link() ); ?>"><?php _e( 'Download', 'wporg-plugins' ); ?></a>
+			<?php endif; ?>
 		</div>
 
 		<?php the_title( '<h1 class="plugin-title"><a href="' . esc_url( get_permalink() ) . '">', '</a></h1>' ); ?>
Index: themes/pub/wporg-plugins/template-parts/section-advanced.php
===================================================================
--- themes/pub/wporg-plugins/template-parts/section-advanced.php	(revision 6074)
+++ themes/pub/wporg-plugins/template-parts/section-advanced.php	(working copy)
@@ -40,7 +40,7 @@
 		// List Trunk, followed by the most recent non-stable release.
 		$tags = array_reverse( $tags );
 
-		if ( $tags ) {
+		if ( $tags && 'publish' == get_post()->post_status ) {
 			echo '<h5>' . __( 'Previous Versions', 'wporg-plugins' ) . '</h5>';
 
 			echo '<div class="plugin-notice notice notice-info notice-alt"><p>' . __( 'Previous versions of this plugin may not be secure or stable and are available for testing purposes only.', 'wporg-plugins' ) . '</p></div>';
