diff --git a/docs/_static/css/custom_log.css b/docs/_static/css/custom_log.css index 61f65d019..57d0cf6d1 100644 --- a/docs/_static/css/custom_log.css +++ b/docs/_static/css/custom_log.css @@ -27,3 +27,27 @@ div.output_area.stderr { div.output_area.stdout { color: #d3d3d3 !important; } + +.sglang-docs-deprecation-banner { + background: #fff4cc; + border-bottom: 1px solid #d8a21f; + color: #2f2a1f; + font-size: 0.95rem; + line-height: 1.45; + overflow-wrap: anywhere; + padding: 0.75rem 1.25rem; + position: relative; + text-align: center; + z-index: 1030; +} + +.sglang-docs-deprecation-banner a { + color: #1f5fbf; + font-weight: 600; + text-decoration: underline; +} + +.sglang-docs-deprecation-banner a:focus, +.sglang-docs-deprecation-banner a:hover { + color: #143f80; +} diff --git a/docs/_static/js/deprecation_banner.js b/docs/_static/js/deprecation_banner.js new file mode 100644 index 000000000..87c8d73fa --- /dev/null +++ b/docs/_static/js/deprecation_banner.js @@ -0,0 +1,49 @@ +(function () { + "use strict"; + + var oldOrigin = "https://sgl-project.github.io"; + var newOrigin = "https://docs.sglang.io"; + + function buildNewDocsUrl() { + var href = window.location.href; + + if (href === oldOrigin || href.indexOf(oldOrigin + "/") === 0) { + return href.replace(oldOrigin, newOrigin); + } + + return newOrigin + window.location.pathname + window.location.search + window.location.hash; + } + + function addDeprecationBanner() { + if (document.getElementById("sglang-docs-deprecation-banner")) { + return; + } + + var link = document.createElement("a"); + link.href = buildNewDocsUrl(); + link.textContent = link.href; + + var banner = document.createElement("div"); + banner.id = "sglang-docs-deprecation-banner"; + banner.className = "sglang-docs-deprecation-banner"; + banner.setAttribute("role", "status"); + banner.setAttribute("aria-live", "polite"); + + var prefix = document.createTextNode( + "This legacy documentation site will be deprecated soon. Please use the new SGLang documentation at " + ); + var suffix = document.createTextNode("."); + + banner.appendChild(prefix); + banner.appendChild(link); + banner.appendChild(suffix); + + document.body.insertBefore(banner, document.body.firstChild); + } + + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", addDeprecationBanner); + } else { + addDeprecationBanner(); + } +})(); diff --git a/docs/conf.py b/docs/conf.py index d6ca64d88..6140b47f8 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -131,6 +131,7 @@ html_context = { html_static_path = ["_static"] html_css_files = ["css/custom_log.css"] +html_js_files = ["js/deprecation_banner.js"] def setup(app): diff --git a/scripts/ci/check_no_docs_changes.py b/scripts/ci/check_no_docs_changes.py index fb302439b..9ab5f32ae 100755 --- a/scripts/ci/check_no_docs_changes.py +++ b/scripts/ci/check_no_docs_changes.py @@ -13,6 +13,12 @@ The documentation has been migrated. Please make documentation updates in the corresponding location under docs_new/ instead. """ +LEGACY_DOCS_ALLOWLIST = { + "docs/_static/css/custom_log.css", + "docs/_static/js/deprecation_banner.js", + "docs/conf.py", +} + def staged_paths() -> list[str]: result = subprocess.run( @@ -33,7 +39,10 @@ def staged_paths() -> list[str]: def main() -> int: paths = sys.argv[1:] or staged_paths() docs_paths = sorted( - path for path in paths if path == "docs" or path.startswith("docs/") + path + for path in paths + if (path == "docs" or path.startswith("docs/")) + and path not in LEGACY_DOCS_ALLOWLIST ) if not docs_paths: