src/Seo.php
public function init ()
	{
		parent::init();
		self::$i = self::getInstance();

		$craft = \Craft::$app;

		// Components
		// ---------------------------------------------------------------------

		$this->setComponents([
			'seo' => SeoService::class,
			'sitemap' => SitemapService::class,
			'redirects' => RedirectsService::class,
			'upgrade' => UpgradeService::class,
		]);

		// Events
		// ---------------------------------------------------------------------

		// User Permissions
		if ($craft->getEdition() !== \Craft::Solo) {
			Event::on(
				UserPermissions::class,
				UserPermissions::EVENT_REGISTER_PERMISSIONS,
				[$this, 'onRegisterPermissions']
			);
		}

		// CP URLs
		Event::on(
			UrlManager::class,
			UrlManager::EVENT_REGISTER_CP_URL_RULES,
			[$this, 'onRegisterCPUrlRules']
		);

		// Site URLs
		Event::on(
			UrlManager::class,
			UrlManager::EVENT_REGISTER_SITE_URL_RULES,
			[$this, 'onRegisterSiteUrlRules']
		);

		// Field type
		Event::on(
			Fields::class,
			Fields::EVENT_REGISTER_FIELD_TYPES,
			[$this, 'onRegisterFieldTypes']
		);

		// Variable
		Event::on(
			CraftVariable::class,
			CraftVariable::EVENT_INIT,
			[$this, 'onRegisterVariable']
		);

		// 404 Exceptions
		if (
			$craft->request->isSiteRequest
			&& !$craft->request->isConsoleRequest
			&& !$craft->request->isLivePreview
		) {
			Event::on(
				ErrorHandler::class,
				ErrorHandler::EVENT_BEFORE_HANDLE_EXCEPTION,
				[$this, 'onBeforeHandleException']
			);
		}

		if ($craft->request->isSiteRequest)
		{
			// Request Headers
			Event::on(
				Application::class,
				Application::EVENT_AFTER_REQUEST,
				[$this, 'onAfterRequest']
			);

			// Template Hook
			$craft->view->hook('seo', [$this, 'onRegisterSeoHook']);
		}

		if ($craft->request->isSiteRequest || $craft->request->isCpRequest)
		{
			// Twig Extension
			$craft->view->registerTwigExtension(new Extension());
		}

		// CraftQL Support
		/** @noinspection PhpUndefinedNamespaceInspection */
		/** @noinspection PhpUnnecessaryFullyQualifiedNameInspection */
		if (class_exists(\markhuot\CraftQL\CraftQL::class)) {
			Event::on(
				SeoField::class,
				'craftQlGetFieldSchema',
				[new GetCraftQLSchema, 'handle']
			);
		}
	}
public function init ()
	{
		parent::init();
		self::$i = self::getInstance();

		$craft = \Craft::$app;

		// Components
		// ---------------------------------------------------------------------

		$this->setComponents([
			'seo' => SeoService::class,
			'sitemap' => SitemapService::class,
			'redirects' => RedirectsService::class,
			'upgrade' => UpgradeService::class,
		]);

		// Events
		// ---------------------------------------------------------------------

		// User Permissions
		if ($craft->getEdition() !== \Craft::Solo) {
			Event::on(
				UserPermissions::class,
				UserPermissions::EVENT_REGISTER_PERMISSIONS,
				[$this, 'onRegisterPermissions']
			);
		}

		// CP URLs
		Event::on(
			UrlManager::class,
			UrlManager::EVENT_REGISTER_CP_URL_RULES,
			[$this, 'onRegisterCPUrlRules']
		);

		// Site URLs
		Event::on(
			UrlManager::class,
			UrlManager::EVENT_REGISTER_SITE_URL_RULES,
			[$this, 'onRegisterSiteUrlRules']
		);

		// Field type
		Event::on(
			Fields::class,
			Fields::EVENT_REGISTER_FIELD_TYPES,
			[$this, 'onRegisterFieldTypes']
		);

		// Variable
		Event::on(
			CraftVariable::class,
			CraftVariable::EVENT_INIT,
			[$this, 'onRegisterVariable']
		);

		// 404 Exceptions
		if (
			$craft->request->isSiteRequest
			&& !$craft->request->isConsoleRequest
			&& !$craft->request->isLivePreview
		) {
			Event::on(
				ErrorHandler::class,
				ErrorHandler::EVENT_BEFORE_HANDLE_EXCEPTION,
				[$this, 'onBeforeHandleException']
			);
		}

		if ($craft->request->isSiteRequest)
		{
			// Request Headers
			Event::on(
				Application::class,
				Application::EVENT_AFTER_REQUEST,
				[$this, 'onAfterRequest']
			);

			// Template Hook
			$craft->view->hook('seo', [$this, 'onRegisterSeoHook']);
		}

		if ($craft->request->isSiteRequest || $craft->request->isCpRequest)
		{
			// Twig Extension
			$craft->view->registerTwigExtension(new Extension());
		}

		// CraftQL Support
		/** @noinspection PhpUndefinedNamespaceInspection */
		/** @noinspection PhpUnnecessaryFullyQualifiedNameInspection */
		if (class_exists(\markhuot\CraftQL\CraftQL::class)) {
			Event::on(
				SeoField::class,
				'craftQlGetFieldSchema',
				[new GetCraftQLSchema, 'handle']
			);
		}
	}
=========================================================================