1+ """mkdocs hooks for adding custom logic to documentation pipeline.
2+
3+ Lifecycle events: https://www.mkdocs.org/dev-guide/plugins/#events
4+ """
5+
16import logging
27import os
38import posixpath
49import re
510from typing import Any , Dict
611
12+ from bs4 import BeautifulSoup
13+ from mkdocs .config .defaults import MkDocsConfig
714from mkdocs .structure .files import Files , File
815from mkdocs .structure .pages import Page
916
101108 "how-tos/deploy-self-hosted.md" : "cloud/deployment/self_hosted_data_plane.md" ,
102109 "concepts/self_hosted.md" : "concepts/langgraph_self_hosted_data_plane.md" ,
103110 # assistant redirects
104- "cloud/how-tos/assistant_versioning.md" : "cloud/how-tos/configuration_cloud.md"
105-
111+ "cloud/how-tos/assistant_versioning.md" : "cloud/how-tos/configuration_cloud.md" ,
106112}
107113
108114
@@ -292,7 +298,7 @@ def on_page_markdown(markdown: str, page: Page, **kwargs: Dict[str, Any]):
292298"""
293299
294300
295- def write_html (site_dir , old_path , new_path ):
301+ def _write_html (site_dir , old_path , new_path ):
296302 """Write an HTML file in the site_dir with a meta redirect to the new page"""
297303 # Determine all relevant paths
298304 old_path_abs = os .path .join (site_dir , old_path )
@@ -308,6 +314,52 @@ def write_html(site_dir, old_path, new_path):
308314 f .write (content )
309315
310316
317+ def _inject_gtm (html : str ) -> str :
318+ """Inject Google Tag Manager code into the HTML.
319+
320+ Code to inject Google Tag Manager noscript tag immediately after <body>.
321+
322+ This is done via hooks rather than via a template because the MkDocs material
323+ theme does not seem to allow placing the code immediately after the <body> tag
324+ without modifying the template files directly.
325+
326+ Args:
327+ html: The HTML content to modify.
328+
329+ Returns:
330+ The modified HTML content with GTM code injected.
331+ """
332+ # Code was copied from Google Tag Manager setup instructions.
333+ gtm_code = """
334+ <!-- Google Tag Manager (noscript) -->
335+ <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-T35S4S46"
336+ height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
337+ <!-- End Google Tag Manager (noscript) -->
338+ """
339+ soup = BeautifulSoup (html , "html.parser" )
340+ body = soup .body
341+ if body :
342+ # Insert the GTM code as raw HTML at the top of <body>
343+ body .insert (0 , BeautifulSoup (gtm_code , "html.parser" ))
344+ return str (soup )
345+ else :
346+ return html # fallback if no <body> found
347+
348+
349+ def on_post_page (output : str , page : Page , config : MkDocsConfig ) -> str :
350+ """Inject Google Tag Manager noscript tag immediately after <body>.
351+
352+ Args:
353+ output: The HTML output of the page.
354+ page: The page instance.
355+ config: The MkDocs configuration object.
356+
357+ Returns:
358+ modified HTML output with GTM code injected.
359+ """
360+ return _inject_gtm (output )
361+
362+
311363# Create HTML files for redirects after site dir has been built
312364def on_post_build (config ):
313365 use_directory_urls = config .get ("use_directory_urls" )
@@ -324,4 +376,4 @@ def on_post_build(config):
324376 + hash
325377 + suffix
326378 )
327- write_html (config ["site_dir" ], old_html_path , new_html_path )
379+ _write_html (config ["site_dir" ], old_html_path , new_html_path )
0 commit comments