diff --git a/client_src/register-drupal-store.js b/client_src/register-drupal-store.js
index f85315a..ee06977 100644
--- a/client_src/register-drupal-store.js
+++ b/client_src/register-drupal-store.js
@@ -42,7 +42,11 @@ export default function registerDrupalStore(data) {
 
     resolvers: {
       async getBlock( state, item ) {
-        const response = await fetch(`${drupalSettings.path.baseUrl}editor/blocks/load/${item}`);
+        const params = {
+          currentPath: window.location.pathname,
+        };
+        var query = Object.keys(params).map(k => `${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`).join('&');
+        const response = await fetch(`${drupalSettings.path.baseUrl}editor/blocks/load/${item}?${query}`);
         const block = await response.json();
         dispatch( 'drupal' ).setBlock( item, block );
         return block;
@@ -50,4 +54,4 @@ export default function registerDrupalStore(data) {
     },
     
   });
-}
\ No newline at end of file
+}
diff --git a/gutenberg.services.yml b/gutenberg.services.yml
index f67c485..5a7e313 100644
--- a/gutenberg.services.yml
+++ b/gutenberg.services.yml
@@ -2,3 +2,7 @@ services:
   plugin.manager.gutenberg.plugin:
     class: Drupal\gutenberg\GutenbergPluginManager
     parent: default_plugin_manager
+
+  gutenberg.block_manager:
+    class: Drupal\gutenberg\GutenbergBlockManager
+    arguments: ['@router', '@plugin.manager.block', '@context.repository', '@context.handler', '@request_stack']
diff --git a/src/Controller/BlocksController.php b/src/Controller/BlocksController.php
index a3490f4..c25d3e2 100644
--- a/src/Controller/BlocksController.php
+++ b/src/Controller/BlocksController.php
@@ -3,15 +3,43 @@
 namespace Drupal\gutenberg\Controller;
 
 use Drupal\Core\Controller\ControllerBase;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\HttpFoundation\JsonResponse;
 use Symfony\Component\HttpFoundation\Request;
 use Drupal\block\Entity\Block;
+use Drupal\gutenberg\GutenbergBlockManager;
 
 /**
  * Returns responses for our blocks routes.
  */
 class BlocksController extends ControllerBase {
   /**
+   * The gutenberg block manager service
+   *
+   * @var \Drupal\gutenberg\GutenbergBlockManager
+   */
+  protected $blockManager;
+
+  /**
+   * Constructs a BlocksController object
+   *
+   * @param \Drupal\gutenberg\GutenbergBlockManager $block_manager
+   *   The gutenberg block manager service to use.
+   */
+  public function __construct(GutenbergBlockManager $block_manager) {
+    $this->blockManager = $block_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('gutenberg.block_manager')
+    );
+  }
+
+  /**
    * Returns JSON representing the loaded blocks.
    *
    * @param \Symfony\Component\HttpFoundation\Request $request
@@ -21,11 +49,7 @@ class BlocksController extends ControllerBase {
    *   The JSON response.
    */
   public function load(Request $request) {
-    $blockManager = \Drupal::service('plugin.manager.block');
-    $contextRepository = \Drupal::service('context.repository');
-    // Get blocks definition
-    $definitions = $blockManager->getDefinitionsForContexts($contextRepository->getAvailableContexts());
-    $definitions = $blockManager->getSortedDefinitions($definitions);
+    $definitions = $this->blockManager->getSortedDefinitions();
     return new JsonResponse($definitions);
   }
 
@@ -41,9 +65,7 @@ class BlocksController extends ControllerBase {
    *   The JSON response.
    */
   public function loadById(Request $request, $plugin_id) {
-    $block_manager = \Drupal::service('plugin.manager.block');
-    $config = [];
-    $plugin_block = $block_manager->createInstance($plugin_id, $config);
+    $plugin_block = $this->blockManager->loadByIdWithForcedContext($plugin_id);
 
     // Some blocks might implement access check.
     $access_result = $plugin_block->access(\Drupal::currentUser());
@@ -56,7 +78,7 @@ class BlocksController extends ControllerBase {
     }
 
     $render = $plugin_block->build();
-    $content = \Drupal::service('renderer')->render($render);
+    $content = \Drupal::service('renderer')->renderRoot($render);
 
     // If the block is a view with contexts defined, it may
     // not render on the editor because of, for example, the
@@ -68,4 +90,4 @@ class BlocksController extends ControllerBase {
     return new JsonResponse(['html' => $content]);
   }
 
-}
\ No newline at end of file
+}
diff --git a/src/GutenbergBlockManager.php b/src/GutenbergBlockManager.php
new file mode 100644
index 0000000..3582c46
--- /dev/null
+++ b/src/GutenbergBlockManager.php
@@ -0,0 +1,169 @@
+<?php
+
+namespace Drupal\gutenberg;
+
+use Drupal\Core\Block\BlockManagerInterface;
+use Drupal\Core\Routing\AccessAwareRouterInterface;
+use Drupal\Core\Plugin\Context\ContextHandlerInterface;
+use Drupal\Core\Plugin\Context\ContextRepositoryInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\RequestStack;
+
+/**
+ * Provides a BlockManager
+ */
+class GutenbergBlockManager {
+
+  /**
+   * The router service.
+   *
+   * @var \Drupal\Core\Routing\AccessAwareRouterInterface
+   */
+  protected $router;
+
+  /**
+   * The block manager service.
+   *
+   * @var \Drupal\Core\Block\BlockManagerInterface
+   */
+  protected $blockManager;
+
+  /**
+   * The context handler service.
+   *
+   * @var \Drupal\Core\Plugin\Context\ContextHandlerInterface
+   */
+  protected $contextHandler;
+
+  /**
+   * The context repository service.
+   *
+   * @var \Drupal\Core\Plugin\Context\ContextRepositoryInterface
+   */
+  protected $contextRepository;
+
+  /**
+   * The request stack.
+   *
+   * @var \Symfony\Component\HttpFoundation\RequestStack
+   */
+  protected $requestStack;
+
+  /**
+   * Constructs a BlockManager object.
+   *
+   * @param \Drupal\Core\Routing\AccessAwareRouterInterface $router
+   *   The router to use.
+   * @param \Drupal\Core\Block\BlockManagerInterface $block_manager
+   *   The block manager to use.
+   * @param \Drupal\Core\Plugin\Context\ContextHandlerInterface
+   *   The context handler to use.
+   * @param \Drupal\Core\Plugin\Context\ContextRepositoryInterface
+   *   The context repository to use.
+   * @param \Symfony\Component\HttpFoundation\RequestStack
+   *   The request stack to use.
+   */
+  public function __construct(AccessAwareRouterInterface $router, BlockManagerInterface $block_manager, ContextRepositoryInterface $context_repository, ContextHandlerInterface $context_handler, RequestStack $request_stack) {
+    $this->router = $router;
+    $this->blockManager = $block_manager;
+    $this->contextRepository = $context_repository;
+    $this->contextHandler = $context_handler;
+    $this->requestStack = $request_stack;
+  }
+
+  /**
+   * Creates a request in the context of the page containing the block.
+   */
+  public function createContextRequest() {
+    $current_request = $this->requestStack->getCurrentRequest();
+    $context_path = $current_request->query->get('currentPath');
+    $context_request = Request::createFromGlobals();
+    $context_request->query->remove('currentPath');
+    $context_request->server->set('REQUEST_URI', $context_path);
+    $this->router->matchRequest($context_request);
+    return $context_request;
+  }
+
+  /**
+   * Gets a sorted list of the definitions for all of the blocks.
+   */
+  public function getSortedDefinitions() {
+    $available_contexts = $this->contextRepository->getAvailableContexts();
+    $definitions = $this->blockManager->getDefinitionsForContexts($available_contexts);
+    $definitions = $this->blockManager->getSortedDefinitions($definitions);
+    return $definitions;
+  }
+
+  /**
+   * Injects the contexts that the block requires.
+   *
+   * @params $block
+   *   The block to set the context mapping for.
+   */
+  public function injectContextsFor($block) {
+    $context_mapping = $block->getContextMapping();
+    $contexts = $this->contextRepository->getRuntimeContexts($context_mapping);
+    $this->contextHandler->applyContextMapping($block, $contexts);
+  }
+
+  /**
+   * Loads a block and then configures it in the context.
+   *
+   * @param string $plugin_id
+   *   The id for the block to load.
+   */
+  public function loadAndConfigureBlock(string $plugin_id) {
+    $block = $this->blockManager->createInstance($plugin_id, []);
+    $this->setContextMappingFor($block);
+    $this->injectContextsFor($block);
+    return $block;
+  }
+
+  /**
+   * Loads the block specified by $plugin_id
+   *
+   * @param string $plugin_id
+   *   The id for the block to load.
+   */
+  public function loadById(string $plugin_id) {
+    return $this->loadAndConfigureBlock($plugin_id);
+  }
+
+  /**
+   * Loads the block specified by $plugin_id in the context of the page
+   * specified by the currentPath query parameter, instead of the normal
+   * context.
+   *
+   * @param string $plugin_id
+   *   The id for the block to load.
+   */
+  public function loadByIdWithForcedContext(string $plugin_id) {
+    $blockContextRequest = $this->createContextRequest();
+    $this->requestStack->push($blockContextRequest);
+    $block = NULL;
+    try {
+      $block = $this->loadAndConfigureBlock($plugin_id);
+    } finally {
+      $this->requestStack->pop();
+    }
+    return $block;
+  }
+
+  /**
+   * Sets the context mapping for the block according to the current context.
+   *
+   * @params $block
+   *   The block to set the context mapping for.
+   */
+  public function setContextMappingFor($block) {
+    $available_contexts = $this->contextRepository->getAvailableContexts();
+    $context_mapping = [];
+    foreach ($block->getContextDefinitions() as $context_slot => $definition) {
+      $valid_contexts = $this->contextHandler->getMatchingContexts($available_contexts, $definition);
+      foreach ($valid_contexts as $context_id => $context) {
+        $context_mapping[$context_slot] = $context_id;
+      }
+    }
+    $block->setContextMapping($context_mapping);
+  }
+}
diff --git a/src/Plugin/Filter/BlockFilter.php b/src/Plugin/Filter/BlockFilter.php
index 10e627e..297042c 100644
--- a/src/Plugin/Filter/BlockFilter.php
+++ b/src/Plugin/Filter/BlockFilter.php
@@ -4,7 +4,11 @@ namespace Drupal\gutenberg\Plugin\Filter;
 
 use Drupal\filter\FilterProcessResult;
 use Drupal\filter\Plugin\FilterBase;
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\gutenberg\GutenbergBlockManager;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * @Filter(
@@ -16,9 +20,34 @@ use Drupal\Core\Form\FormStateInterface;
  *   type = Drupal\filter\Plugin\FilterInterface::TYPE_MARKUP_LANGUAGE,
  * )
  */
-class BlockFilter extends FilterBase {
-  public function process($text, $langcode) {
+class BlockFilter extends FilterBase implements ContainerFactoryPluginInterface {
+  /*
+   * @param \Drupal\gutenberg\GutenbergBlockManager
+   *   The block manager service.
+   */
+  protected $blockManager;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, GutenbergBlockManager $block_manager) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+    $this->blockManager = $block_manager;
+  }
 
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('gutenberg.block_manager')
+    );
+  }
+
+  public function process($text, $langcode) {
     $lines = explode("\n", $text);
 
     $lines = preg_replace_callback('#^<!-- wp:drupalblock\/.*\s(.*)\s\/-->$#', array($this, 'renderBlock'), $lines);
@@ -36,11 +65,7 @@ class BlockFilter extends FilterBase {
     $comment = $match[0];
     $attributes = json_decode($match[1]);
     $plugin_id = $attributes->blockId;
-    $block_manager = \Drupal::service('plugin.manager.block');
-    // You can hard code configuration or you load from settings.
-    $config = [];
-    $plugin_block = $block_manager->createInstance($plugin_id, $config);
-    // Some blocks might implement access check.
+    $plugin_block = $this->blockManager->loadById($plugin_id);
     $access_result = $plugin_block->access(\Drupal::currentUser());
     // Return empty render array if user doesn't have access.
     // $access_result can be boolean or an AccessResult class
