diff --git a/src/content-scripts/content_script/global.ts b/src/content-scripts/content_script/global.ts
index 4b1ebc2496..40e4cae1dc 100644
--- a/src/content-scripts/content_script/global.ts
+++ b/src/content-scripts/content_script/global.ts
@@ -36,7 +36,6 @@ import { PageAnnotationsCache } from 'src/annotations/cache'
 import type { AnalyticsEvent } from 'src/analytics/types'
 import analytics from 'src/analytics'
 import { main as highlightMain } from 'src/content-scripts/content_script/highlights'
-import { main as InPageUIInjectionMain } from 'src/content-scripts/content_script/in-page-ui-injections'
 import type { PageIndexingInterface } from 'src/page-indexing/background/types'
 import { copyToClipboard } from 'src/annotations/content_script/utils'
 import { getUnderlyingResourceUrl } from 'src/util/uri-utils'
@@ -469,16 +468,6 @@ export async function main(
                 components.highlights.resolve()
             }
 
-            if (component === 'search') {
-                await contentScriptRegistry.registerInPageUIInjectionScript(
-                    InPageUIInjectionMain,
-                    {
-                        searchDisplayProps,
-                    },
-                )
-                return
-            }
-
             if (!components[component]) {
                 components[component] = resolvablePromise<void>()
                 loadContentScript(component)
@@ -501,16 +490,16 @@ export async function main(
     ): Promise<{ annotationId: AutoPk; createPromise: Promise<void> }> {
         const handleError = async (err: Error) => {
             captureException(err)
-            await contentScriptRegistry.registerInPageUIInjectionScript(
-                InPageUIInjectionMain,
-                {
+            inPageUI.loadOnDemandInPageUI({
+                component: 'error-display',
+                options: {
                     errorDisplayProps: {
                         errorMessage: err.message,
                         title: 'Error saving note',
                         blockedBackground: true,
                     },
                 },
-            )
+            })
         }
 
         try {
@@ -996,15 +985,16 @@ export async function main(
             })
             components.tooltip?.resolve()
         },
-        async registerInPageUIInjectionScript(execute, onDemandDisplay) {
+        async registerInPageUIInjectionScript(execute) {
             await execute({
+                inPageUI,
                 syncSettingsBG,
                 syncSettings: createSyncSettingsStore({ syncSettingsBG }),
                 requestSearcher: remoteFunction('search'),
+                searchDisplayProps,
                 annotationsFunctions,
-                onDemandDisplay,
-                bgScriptBG,
             })
+            components.in_page_ui_injections?.resolve()
         },
     }
 
@@ -1047,9 +1037,9 @@ export async function main(
         ) ||
         window.location.href.includes('youtube.com')
     ) {
-        await contentScriptRegistry.registerInPageUIInjectionScript(
-            InPageUIInjectionMain,
-        )
+        inPageUI.loadOnDemandInPageUI({
+            component: 'search-engine-integration',
+        })
     }
 
     const pageHasBookark =
@@ -1137,9 +1127,9 @@ export async function main(
                 ) ||
                 window.location.href.includes('youtube.com')
             ) {
-                await contentScriptRegistry.registerInPageUIInjectionScript(
-                    InPageUIInjectionMain,
-                )
+                inPageUI.loadOnDemandInPageUI({
+                    component: 'youtube-integration',
+                })
             }
 
             await injectCustomUIperPage(
@@ -1226,10 +1216,11 @@ export async function main(
     // so it is included in this global content script where it adds less than 500kb.
     await contentScriptRegistry.registerHighlightingScript(highlightMain)
 
+    await inPageUI.loadComponent('in_page_ui_injections')
     if (areHighlightsEnabled) {
         inPageUI.showHighlights()
         if (!annotationsCache.isEmpty) {
-            inPageUI.loadComponent('sidebar')
+            await inPageUI.loadComponent('sidebar')
         }
     }
 
@@ -1239,7 +1230,7 @@ export async function main(
             showPageActivityIndicator: hasActivity,
         })
         if (await tooltipUtils.getTooltipState()) {
-            await inPageUI.setupTooltip()
+            await inPageUI.loadComponent('tooltip')
         }
     } else {
         if (hasActivity) {
@@ -1248,7 +1239,7 @@ export async function main(
                 showPageActivityIndicator: hasActivity,
             })
             if (await tooltipUtils.getTooltipState()) {
-                await inPageUI.setupTooltip()
+                await inPageUI.loadComponent('tooltip')
             }
         }
     }
diff --git a/src/content-scripts/content_script/in-page-ui-injections.ts b/src/content-scripts/content_script/in-page-ui-injections.ts
index f404c824f3..883be7c391 100644
--- a/src/content-scripts/content_script/in-page-ui-injections.ts
+++ b/src/content-scripts/content_script/in-page-ui-injections.ts
@@ -1,6 +1,65 @@
-import { initInPageUIInjections } from 'src/search-injection/content_script'
-import type { InPageUIInjectionsMain } from 'src/content-scripts/content_script/types'
+import * as constants from '../../search-injection/constants'
+import * as utils from '../../search-injection/utils'
+import { handleRenderSearchInjection } from '../../search-injection/searchInjection'
+import { handleRenderYoutubeInterface } from '../../search-injection/youtubeInterface'
+import { renderErrorDisplay } from '../../search-injection/error-display'
+import { renderSearchDisplay } from '../../search-injection/search-display'
+import type { ContentScriptRegistry, InPageUIInjectionsMain } from './types'
 
-export const main: InPageUIInjectionsMain = async (...options) => {
-    initInPageUIInjections(...options)
+export const main: InPageUIInjectionsMain = async ({
+    inPageUI,
+    annotationsFunctions,
+    requestSearcher,
+    searchDisplayProps,
+    syncSettings,
+    syncSettingsBG,
+}) => {
+    inPageUI.events.on(
+        'injectOnDemandInPageUI',
+        async ({ component, options }) => {
+            if (component === 'error-display') {
+                if (options?.errorDisplayProps) {
+                    renderErrorDisplay(options.errorDisplayProps)
+                }
+            } else if (component === 'dashboard') {
+                renderSearchDisplay(searchDisplayProps)
+            } else if (component === 'youtube-integration') {
+                const url = window.location.href
+                if (url.includes('youtube.com')) {
+                    await handleRenderYoutubeInterface(
+                        syncSettings,
+                        syncSettingsBG,
+                        annotationsFunctions,
+                    )
+                }
+            } else if (component === 'search-engine-integration') {
+                const url = window.location.href
+                const matched = utils.matchURL(url)
+
+                if (matched) {
+                    const searchInjection =
+                        (await syncSettings.searchInjection.get(
+                            'searchEnginesEnabled',
+                        )) ?? constants.SEARCH_INJECTION_DEFAULT
+                    if (searchInjection[matched]) {
+                        try {
+                            const query = utils.fetchQuery(url)
+
+                            await handleRenderSearchInjection(
+                                query,
+                                requestSearcher,
+                                matched,
+                                syncSettings,
+                            )
+                        } catch (err) {
+                            console.error(err)
+                        }
+                    }
+                }
+            }
+        },
+    )
 }
+
+const registry = globalThis['contentScriptRegistry'] as ContentScriptRegistry
+registry.registerInPageUIInjectionScript(main)
diff --git a/src/content-scripts/content_script/tooltip.ts b/src/content-scripts/content_script/tooltip.ts
index 3190eb0e9a..d7ebc425eb 100644
--- a/src/content-scripts/content_script/tooltip.ts
+++ b/src/content-scripts/content_script/tooltip.ts
@@ -1,5 +1,4 @@
 import type { ContentScriptRegistry, TooltipScriptMain } from './types'
-
 import { bodyLoader } from 'src/util/loader'
 import { runOnScriptShutdown } from 'src/in-page-ui/tooltip/utils'
 import {
@@ -15,7 +14,7 @@ import { createInPageUI, destroyInPageUI } from 'src/in-page-ui/utils'
 import { IGNORE_CLICK_OUTSIDE_CLASS } from '../constants'
 
 export const main: TooltipScriptMain = async (options) => {
-    const cssFile = browser.runtime.getURL(`/content_script.css`)
+    const cssFile = browser.runtime.getURL(`/content_script_tooltip.css`)
     let mount: InPageUIRootMount | null = null
     const createMount = () => {
         if (!mount) {
@@ -42,7 +41,7 @@ export const main: TooltipScriptMain = async (options) => {
     options.inPageUI.events.on('componentShouldDestroy', async (event) => {
         if (event.component === 'tooltip') {
             destroyInPageUI('tooltip')
-            await removeTooltip()
+            removeTooltip()
         }
     })
     options.inPageUI.events.on('stateChanged', async (event) => {
diff --git a/src/content-scripts/content_script/types.ts b/src/content-scripts/content_script/types.ts
index d8ca847c1c..ba5f23af48 100644
--- a/src/content-scripts/content_script/types.ts
+++ b/src/content-scripts/content_script/types.ts
@@ -6,27 +6,19 @@ import type AnnotationsManager from 'src/annotations/annotations-manager'
 import type { AnnotationInterface } from 'src/annotations/background/types'
 import type { HighlightRendererInterface } from '@worldbrain/memex-common/lib/in-page-ui/highlighting/types'
 import type { ContentFingerprint } from '@worldbrain/memex-common/lib/personal-cloud/storage/types'
-import type { RemoteSyncSettingsInterface } from 'src/sync-settings/background/types'
 import type { PageAnnotationsCacheInterface } from 'src/annotations/cache/types'
 import type { MaybePromise } from 'src/util/types'
 import type { AnalyticsCoreInterface } from '@worldbrain/memex-common/lib/analytics/types'
-import type { SyncSettingsStore } from 'src/sync-settings/util'
-import type { ErrorDisplayProps } from 'src/search-injection/error-display'
 import type { SearchDisplayProps } from 'src/search-injection/search-display'
-import { RemoteBGScriptInterface } from 'src/background-script/types'
+import type { RemoteSyncSettingsInterface } from 'src/sync-settings/background/types'
+import type { SyncSettingsStore } from 'src/sync-settings/util'
 
 export interface ContentScriptRegistry {
     registerRibbonScript(main: RibbonScriptMain): Promise<void>
     registerSidebarScript(main: SidebarScriptMain): Promise<void>
     registerHighlightingScript(main: HighlightsScriptMain): Promise<void>
     registerTooltipScript(main: TooltipScriptMain): Promise<void>
-    registerInPageUIInjectionScript(
-        main: InPageUIInjectionsMain,
-        onDemandDisplay?: {
-            errorDisplayProps?: ErrorDisplayProps
-            searchDisplayProps?: SearchDisplayProps
-        },
-    ): Promise<void>
+    registerInPageUIInjectionScript(main: InPageUIInjectionsMain): Promise<void>
 }
 
 export type SidebarScriptMain = (
@@ -60,6 +52,8 @@ export interface HighlightDependencies {
 }
 
 export interface InPageUIInjectionsDependencies {
+    inPageUI: SharedInPageUIInterface
+    searchDisplayProps: SearchDisplayProps
     requestSearcher: any
     syncSettingsBG: RemoteSyncSettingsInterface
     syncSettings: SyncSettingsStore<
@@ -71,11 +65,6 @@ export interface InPageUIInjectionsDependencies {
         | 'dashboard'
     >
     annotationsFunctions: any
-    onDemandDisplay?: {
-        errorDisplayProps?: ErrorDisplayProps
-        searchDisplayProps?: SearchDisplayProps
-    }
-    bgScriptBG: RemoteBGScriptInterface
 }
 
 export type HighlightsScriptMain = (
@@ -90,8 +79,4 @@ export type InPageUIInjectionsMain = (
     dependencies: InPageUIInjectionsDependencies,
 ) => Promise<void>
 
-export type YoutubeInjectionMain = (
-    dependencies: InPageUIInjectionsDependencies,
-) => Promise<void>
-
 export type GetContentFingerprints = () => Promise<ContentFingerprint[]>
diff --git a/src/content-scripts/types.ts b/src/content-scripts/types.ts
index c0388b6d28..54d6228353 100644
--- a/src/content-scripts/types.ts
+++ b/src/content-scripts/types.ts
@@ -3,4 +3,4 @@ export type ContentScriptComponent =
     | 'sidebar'
     | 'ribbon'
     | 'highlights'
-    | 'search_injection'
+    | 'in_page_ui_injections'
diff --git a/src/in-page-ui/keyboard-shortcuts/content_script/index.ts b/src/in-page-ui/keyboard-shortcuts/content_script/index.ts
index d9be9144ea..e001d59c7f 100644
--- a/src/in-page-ui/keyboard-shortcuts/content_script/index.ts
+++ b/src/in-page-ui/keyboard-shortcuts/content_script/index.ts
@@ -101,7 +101,8 @@ function getShortcutHandlers({
             }
         },
         createBookmark: () => inPageUI.showRibbon({ action: 'bookmark' }),
-        openDashboard: () => inPageUI.showSearch(),
+        openDashboard: async () =>
+            inPageUI.loadOnDemandInPageUI({ component: 'dashboard' }),
         openDashboardInNewTab: () =>
             runInBackground<InPageUIInterface<'caller'>>().openDashboard(),
         toggleSidebar: () => inPageUI.toggleSidebar(),
diff --git a/src/in-page-ui/ribbon/react/containers/ribbon/logic.ts b/src/in-page-ui/ribbon/react/containers/ribbon/logic.ts
index 6bf909bfb5..d6d34ab03c 100644
--- a/src/in-page-ui/ribbon/react/containers/ribbon/logic.ts
+++ b/src/in-page-ui/ribbon/react/containers/ribbon/logic.ts
@@ -384,11 +384,13 @@ export class RibbonContainerLogic extends UILogic<
             action: 'rabbit_hole_open',
         })
     }
-    toggleQuickSearch: EventHandler<'toggleQuickSearch'> = async ({
-        previousState,
-    }) => {
-        await this.dependencies.inPageUI.showSearch()
+
+    toggleQuickSearch: EventHandler<'toggleQuickSearch'> = async ({}) => {
+        this.dependencies.inPageUI.loadOnDemandInPageUI({
+            component: 'dashboard',
+        })
     }
+
     toggleTheme: EventHandler<'toggleTheme'> = async ({ previousState }) => {
         await browser.storage.local.set({
             themeVariant:
diff --git a/src/in-page-ui/shared-state/shared-in-page-ui-state.ts b/src/in-page-ui/shared-state/shared-in-page-ui-state.ts
index eede003ffc..ef5a598bb2 100644
--- a/src/in-page-ui/shared-state/shared-in-page-ui-state.ts
+++ b/src/in-page-ui/shared-state/shared-in-page-ui-state.ts
@@ -33,25 +33,26 @@ export interface SharedInPageUIDependencies {
  *
  */
 export class SharedInPageUIState implements SharedInPageUIInterface {
-    contentSharingEvents: TypedRemoteEventEmitter<'contentSharing'>
-    summarisePageEvents: TypedRemoteEventEmitter<'pageSummary'>
+    private contentSharingEvents: TypedRemoteEventEmitter<'contentSharing'>
+    private summarisePageEvents: TypedRemoteEventEmitter<'pageSummary'>
+
     events = new EventEmitter() as TypedEventEmitter<SharedInPageUIEvents>
     componentsShown: InPageUIComponentShowState = {
         ribbon: false,
-        search: false,
         sidebar: false,
         tooltip: false,
         highlights: false,
+        in_page_ui_injections: false,
     }
-    componentsSetUp: InPageUIComponentShowState = {
+    private componentsSetUp: InPageUIComponentShowState = {
         ribbon: false,
-        search: false,
         sidebar: false,
         tooltip: false,
         highlights: false,
+        in_page_ui_injections: false,
     }
 
-    ribbonEnabled = null
+    private ribbonEnabled = null
 
     /**
      * Keep track of currently selected space for other UI elements to follow.
@@ -68,7 +69,7 @@ export class SharedInPageUIState implements SharedInPageUIInterface {
     selectedList: SharedInPageUIInterface['selectedList'] = null
     cacheLoadPromise: SharedInPageUIInterface['cacheLoadPromise'] = resolvablePromise()
 
-    _pendingEvents: {
+    private _pendingEvents: {
         sidebarAction?: {
             emittedWhen: number
         } & SidebarActionOptions
@@ -102,7 +103,7 @@ export class SharedInPageUIState implements SharedInPageUIInterface {
         })
     }
 
-    _handleNewListener = (
+    private _handleNewListener = (
         eventName: keyof SharedInPageUIEvents,
         listener: (...args: any[]) => void,
     ) => {
@@ -152,7 +153,14 @@ export class SharedInPageUIState implements SharedInPageUIInterface {
         maybeEmitAction()
     }
 
-    _emitAction(
+    loadOnDemandInPageUI: SharedInPageUIInterface['loadOnDemandInPageUI'] = ({
+        component,
+        options,
+    }) => {
+        this.events.emit('injectOnDemandInPageUI', { component, options })
+    }
+
+    private _emitAction(
         params:
             | ({
                   type: 'sidebarAction'
@@ -193,10 +201,6 @@ export class SharedInPageUIState implements SharedInPageUIInterface {
         return
     }
 
-    async showSearch() {
-        await this.options.loadComponent('search')
-    }
-
     async showRibbon(options?: { action?: InPageUIRibbonAction }) {
         this.ribbonEnabled = await sidebarUtils.getSidebarState()
         const maybeEmitAction = () => {
@@ -249,10 +253,6 @@ export class SharedInPageUIState implements SharedInPageUIInterface {
         this.events.emit('ribbonUpdate')
     }
 
-    async setupTooltip() {
-        await this.loadComponent('tooltip')
-    }
-
     async showTooltip() {
         await this._setState('tooltip', true)
     }
diff --git a/src/in-page-ui/shared-state/types.ts b/src/in-page-ui/shared-state/types.ts
index 61d6bf7d6c..f395f7d3e7 100644
--- a/src/in-page-ui/shared-state/types.ts
+++ b/src/in-page-ui/shared-state/types.ts
@@ -6,6 +6,11 @@ import type {
     UnifiedList,
 } from 'src/annotations/cache/types'
 import type { Resolvable } from 'src/util/resolvable'
+import type {
+    OnDemandInPageUIComponents,
+    OnDemandInPageUIProps,
+} from 'src/search-injection/types'
+import type { ContentScriptComponent } from 'src/content-scripts/types'
 
 export type InPageUISidebarAction =
     | 'comment'
@@ -29,12 +34,7 @@ export type InPageUISidebarAction =
     | 'save_image_as_new_note'
 
 export type InPageUIRibbonAction = 'comment' | 'tag' | 'list' | 'bookmark'
-export type InPageUIComponent =
-    | 'ribbon'
-    | 'sidebar'
-    | 'tooltip'
-    | 'highlights'
-    | 'search'
+export type InPageUIComponent = ContentScriptComponent
 
 export type InPageUIComponentShowState = {
     [Component in InPageUIComponent]: boolean
@@ -79,6 +79,10 @@ export interface SharedInPageUIEvents {
         options?: ShouldSetUpOptions
     }) => void
     componentShouldDestroy: (event: { component: InPageUIComponent }) => void
+    injectOnDemandInPageUI: (event: {
+        component: OnDemandInPageUIComponents
+        options?: OnDemandInPageUIProps
+    }) => void
 }
 
 export interface ShouldSetUpOptions {
@@ -112,7 +116,6 @@ export interface SharedInPageUIInterface {
     // Tooltip
     showTooltip(): Promise<void>
     hideTooltip(): Promise<void>
-    setupTooltip(): Promise<void>
     removeTooltip(): Promise<void>
     toggleTooltip(): Promise<void>
 
@@ -122,5 +125,8 @@ export interface SharedInPageUIInterface {
     toggleHighlights(): Promise<void>
 
     // On-demand in-page UIs
-    showSearch(): Promise<void>
+    loadOnDemandInPageUI(params: {
+        component: OnDemandInPageUIComponents
+        options?: OnDemandInPageUIProps
+    }): void
 }
diff --git a/src/in-page-ui/tooltip/types.ts b/src/in-page-ui/tooltip/types.ts
index 35541cdad5..167648ddf2 100644
--- a/src/in-page-ui/tooltip/types.ts
+++ b/src/in-page-ui/tooltip/types.ts
@@ -1,11 +1,6 @@
 import type { SharedInPageUIInterface } from 'src/in-page-ui/shared-state/types'
 import type { AnnotationFunctions } from '@worldbrain/memex-common/lib/in-page-ui/types'
 
-export type TooltipInPageUIInterface = Pick<
-    SharedInPageUIInterface,
-    'events' | 'hideTooltip' | 'showTooltip' | 'removeTooltip' | 'showSidebar'
->
-
 export interface TooltipDependencies extends AnnotationFunctions {
     inPageUI: SharedInPageUIInterface
 }
diff --git a/src/manifest-v3.json b/src/manifest-v3.json
index bbbb4527b6..6769a89b2e 100644
--- a/src/manifest-v3.json
+++ b/src/manifest-v3.json
@@ -23,7 +23,7 @@
         {
             "matches": ["<all_urls>"],
             "js": ["lib/browser-polyfill.js", "content_script.js"],
-            "css": ["/content_script.css"],
+            "css": [],
             "run_at": "document_end"
         }
     ],
diff --git a/src/manifest.json b/src/manifest.json
index 0d9143d672..6186f978cf 100644
--- a/src/manifest.json
+++ b/src/manifest.json
@@ -17,7 +17,7 @@
         {
             "matches": ["<all_urls>"],
             "js": ["lib/browser-polyfill.js", "content_script.js"],
-            "css": ["/content_script.css"],
+            "css": [],
             "run_at": "document_end"
         }
     ],
diff --git a/src/search-injection/content_script.ts b/src/search-injection/content_script.ts
deleted file mode 100644
index c303d67c10..0000000000
--- a/src/search-injection/content_script.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import * as constants from './constants'
-import * as utils from './utils'
-import { handleRenderSearchInjection } from './searchInjection'
-import { handleRenderYoutubeInterface } from './youtubeInterface'
-import { renderErrorDisplay } from './error-display'
-import { renderSearchDisplay } from './search-display'
-import type { InPageUIInjectionsDependencies } from 'src/content-scripts/content_script/types'
-
-const url = window.location.href
-const matched = utils.matchURL(url)
-
-/**
- * Fetches SearchInjection user preferance from storage.
- * If set, proceed with matching URL and fetching search query
- */
-export async function initInPageUIInjections({
-    syncSettings,
-    syncSettingsBG,
-    requestSearcher,
-    annotationsFunctions,
-    onDemandDisplay,
-}: InPageUIInjectionsDependencies) {
-    if (onDemandDisplay?.errorDisplayProps != null) {
-        renderErrorDisplay(onDemandDisplay.errorDisplayProps)
-        return
-    }
-
-    if (onDemandDisplay?.searchDisplayProps != null) {
-        renderSearchDisplay(onDemandDisplay.searchDisplayProps)
-        return
-    }
-
-    if (url.includes('youtube.com')) {
-        await handleRenderYoutubeInterface(
-            syncSettings,
-            syncSettingsBG,
-            annotationsFunctions,
-        )
-        return
-    }
-
-    if (matched) {
-        const searchInjection =
-            (await syncSettings.searchInjection.get('searchEnginesEnabled')) ??
-            constants.SEARCH_INJECTION_DEFAULT
-        if (searchInjection[matched]) {
-            try {
-                const query = utils.fetchQuery(url)
-
-                await handleRenderSearchInjection(
-                    query,
-                    requestSearcher,
-                    matched,
-                    syncSettings,
-                )
-            } catch (err) {
-                console.error(err)
-            }
-        }
-    }
-}
diff --git a/src/search-injection/types.ts b/src/search-injection/types.ts
index 639207d5d7..52fd3b6fd5 100644
--- a/src/search-injection/types.ts
+++ b/src/search-injection/types.ts
@@ -1,3 +1,5 @@
+import type { ErrorDisplayProps } from './error-display'
+
 export type SearchEngineName = 'google' | 'duckduckgo' | 'brave' | 'bing'
 export interface SearchEngineInfo {
     regex: RegExp // Regular Expression to match the url
@@ -21,3 +23,13 @@ export interface ResultItemProps {
     tags: []
     onLinkClick: React.MouseEventHandler
 }
+
+export interface OnDemandInPageUIProps {
+    errorDisplayProps?: ErrorDisplayProps
+}
+
+export type OnDemandInPageUIComponents =
+    | 'youtube-integration'
+    | 'search-engine-integration'
+    | 'dashboard'
+    | 'error-display'