diff --git a/external-permalinks-redux.php b/external-permalinks-redux.php
index 5b1829c4e455e92a62b5003d81e96f4dc928d6ed..371686b3ffb42b2aa788b890ba3eb5b2515cc574 100644
--- a/external-permalinks-redux.php
+++ b/external-permalinks-redux.php
@@ -24,6 +24,9 @@
  * @package External_Permalinks_Redux
  */
 
+// Include singleton trait used by all classes.
+require_once dirname( __FILE__ ) . '/inc/trait-singleton.php';
+
 // Include block-editor class.
 require_once dirname( __FILE__ ) . '/inc/class-external-permalinks-redux-block-editor.php';
 
@@ -32,12 +35,7 @@ require_once dirname( __FILE__ ) . '/inc/class-external-permalinks-redux-block-e
  */
 // phpcs:ignore PEAR.NamingConventions.ValidClassName, Squiz.Commenting.ClassComment.Missing
 class external_permalinks_redux {
-	/**
-	 * Singleton!
-	 *
-	 * @var self
-	 */
-	protected static $instance;
+	use External_Permalinks_Redux_Singleton;
 
 	/**
 	 * Redirect URL meta key.
@@ -61,29 +59,70 @@ class external_permalinks_redux {
 	public $status_codes;
 
 	/**
-	 * Instance of the block-editor integration class.
+	 * Supported post types.
+	 *
+	 * Cannot be used before `admin_init` hook.
 	 *
-	 * @var External_Permalinks_Redux_Block_Editor
+	 * @var array
 	 */
-	public $block_editor;
+	private $post_types;
 
 	/**
-	 * Instantiate class as a singleton.
+	 * Allow access to certain private properties.
 	 *
-	 * @return object
+	 * @param string $name Property name.
+	 * @return array|null
 	 */
-	public static function get_instance() {
-		if ( ! isset( self::$instance ) ) {
-			self::$instance = new self();
+	public function __get( $name ) {
+		if ( 'post_types' === $name ) {
+			if ( ! did_action( 'admin_init' ) ) {
+				_doing_it_wrong(
+					__METHOD__,
+					'Cannot be used before `admin_init` hook.',
+					'1.0'
+				);
+			}
+
+			return $this->post_types;
 		}
 
-		return self::$instance;
+		return null;
+	}
+
+	/**
+	 * Disallow setting private properties except via filters.
+	 *
+	 * @param string $name Property name.
+	 * @param mixed $value Property value.
+	 * @return false
+	 */
+	public function __set( $name, $value ) {
+		return false;
+	}
+
+	/**
+	 * Check if certain private properties are set.
+	 *
+	 * @param string $name Property name.
+	 * @return bool
+	 */
+	public function __isset( $name ) {
+		if ( 'post_types' === $name ) {
+			if ( ! did_action( 'admin_init' ) ) {
+				return false;
+			}
+
+			return is_array( $this->post_types )
+				&& ! empty( $this->post_types );
+		}
+
+		return false;
 	}
 
 	/**
 	 * Register actions and filters.
 	 */
-	private function __construct() {
+	protected function _setup() {
 		add_action( 'init', array( $this, 'action_init' ), 0 ); // Other init actions may rely on permalinks so filter early.
 		add_action( 'admin_init', array( $this, 'action_admin_init' ) );
 		add_action( 'save_post', array( $this, 'action_save_post' ) );
@@ -92,8 +131,6 @@ class external_permalinks_redux {
 		add_filter( 'post_type_link', array( $this, 'filter_post_permalink' ), 1, 2 );
 		add_filter( 'page_link', array( $this, 'filter_page_link' ), 1, 2 );
 		add_action( 'wp', array( $this, 'action_wp' ) );
-
-		$this->block_editor = new External_Permalinks_Redux_Block_Editor();
 	}
 
 	/**
@@ -116,13 +153,13 @@ class external_permalinks_redux {
 	 * Add meta box.
 	 */
 	public function action_admin_init() {
-		$post_types = apply_filters( 'epr_post_types', array( 'post', 'page' ) );
+		$this->post_types = apply_filters( 'epr_post_types', array( 'post', 'page' ) );
 
-		if ( ! is_array( $post_types ) ) {
+		if ( ! is_array( $this->post_types ) ) {
 			return;
 		}
 
-		foreach ( $post_types as $post_type ) {
+		foreach ( $this->post_types as $post_type ) {
 			if (
 				function_exists( 'use_block_editor_for_post_type' )
 				&& use_block_editor_for_post_type( $post_type )
@@ -298,6 +335,7 @@ class external_permalinks_redux {
 
 // Initialize the plugin if it hasn't already.
 external_permalinks_redux::get_instance();
+External_Permalinks_Redux_Block_Editor::get_instance();
 
 /**
  * Wrapper for meta box function.
diff --git a/inc/class-external-permalinks-redux-block-editor.php b/inc/class-external-permalinks-redux-block-editor.php
index 1406cc5dc304be3955a444467a073c5c3e33978c..bdb075bc60d8c08278d64966def495143d65498d 100644
--- a/inc/class-external-permalinks-redux-block-editor.php
+++ b/inc/class-external-permalinks-redux-block-editor.php
@@ -8,4 +8,15 @@
 /**
  * Class Block_Editor.
  */
-class External_Permalinks_Redux_Block_Editor {}
+class External_Permalinks_Redux_Block_Editor {
+	use External_Permalinks_Redux_Singleton;
+
+	/**
+	 * Set up class.
+	 *
+	 * @return void
+	 */
+	protected function _setup() {
+		// TODO: Implement _setup() method.
+	}
+}
diff --git a/inc/trait-singleton.php b/inc/trait-singleton.php
new file mode 100644
index 0000000000000000000000000000000000000000..ba021a995fd1f75e3581fa56fbc1891905fcdf3b
--- /dev/null
+++ b/inc/trait-singleton.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Singleton trait.
+ *
+ * @package External_Permalinks_Redux
+ */
+
+trait External_Permalinks_Redux_Singleton {
+	/**
+	 * Singleton!
+	 *
+	 * @var self
+	 */
+	protected static $instance;
+
+	/**
+	 * Instantiate class as a singleton.
+	 *
+	 * @return object
+	 */
+	public static function get_instance() {
+		if ( ! isset( self::$instance ) ) {
+			self::$instance = new self();
+			self::$instance->_setup();
+		}
+
+		return self::$instance;
+	}
+
+	/**
+	 * Unused constructor.
+	 */
+	final private function __construct() {}
+
+	/**
+	 * Set up class.
+	 *
+	 * @return void
+	 */
+	abstract protected function _setup();
+}
diff --git a/tests/test-admin-callbacks.php b/tests/test-admin-callbacks.php
index ded6af38746028264a91a07acf6764782dbd66fd..2b37ed38b1be68e9e46fddea00cd11925778f071 100755
--- a/tests/test-admin-callbacks.php
+++ b/tests/test-admin-callbacks.php
@@ -76,6 +76,8 @@ class AdminCallbacks extends WP_UnitTestCase {
 	 * Test metabox save.
 	 */
 	public function test_save_callback() {
+		add_filter( 'use_block_editor_for_post', '__return_false' );
+
 		$_POST[ $this->plugin->meta_key_target . '_nonce' ] = $this->nonce;
 		$_POST[ $this->plugin->meta_key_target . '_url' ] = static::DESTINATION;
 		$_POST[ $this->plugin->meta_key_target . '_type' ] = static::TYPE;