diff --git a/docs/references/api-reference.mdx b/docs/references/api-reference.mdx
index e07980de34..02a9236af0 100644
--- a/docs/references/api-reference.mdx
+++ b/docs/references/api-reference.mdx
@@ -20,49 +20,41 @@ Complete API documentation for all Temporal SDKs and server APIs.
href: "https://dotnet.temporal.io/api/",
title: ".NET SDK API",
description: "Complete .NET SDK API documentation with all namespaces, classes, and methods.",
- external: true,
},
{
href: "https://pkg.go.dev/go.temporal.io/sdk",
title: "Go SDK API",
description: "Complete Go SDK API documentation on pkg.go.dev with all packages, types, and methods.",
- external: true,
},
{
href: "https://www.javadoc.io/doc/io.temporal/temporal-sdk/latest/index.html",
title: "Java SDK API",
description: "Complete Java SDK API documentation on javadoc.io with all classes, interfaces, and annotations.",
- external: true,
},
{
href: "https://php.temporal.io/namespaces/temporal.html",
title: "PHP SDK API",
description: "Complete PHP SDK API documentation with all namespaces, classes, and interfaces.",
- external: true,
},
{
href: "https://python.temporal.io/",
title: "Python SDK API",
description: "Complete Python SDK API documentation with all modules, classes, and functions.",
- external: true,
},
{
href: "https://ruby.temporal.io/",
title: "Ruby SDK API",
description: "Complete Ruby SDK API documentation with all modules, classes, and methods.",
- external: true,
},
{
href: "https://docs.rs/temporalio-sdk/latest/temporalio_sdk/",
title: "Rust SDK API",
description: "Complete Rust SDK API documentation on docs.rs with all modules, structs, and associated functions/methods.",
- external: true,
},
{
href: "https://typescript.temporal.io",
title: "TypeScript SDK API",
description: "Complete TypeScript SDK API documentation with all interfaces, types, and namespaces.",
- external: true,
},
]} />
diff --git a/docs/security.mdx b/docs/security.mdx
index b595e9e9ec..7d798863c2 100644
--- a/docs/security.mdx
+++ b/docs/security.mdx
@@ -18,7 +18,6 @@ Find security information for your Temporal deployment, whether you're using Tem
href: "https://trust.temporal.io",
title: "Company Security",
description: "Learn about Temporal Technologies' general security practices, compliance certifications, and organizational security measures.",
- external: true,
},
{
href: "/evaluate/cloud/security",
@@ -34,6 +33,5 @@ Find security information for your Temporal deployment, whether you're using Tem
href: "https://temporal.io/pages/cloud-security-white-paper",
title: "Temporal Cloud Security Whitepaper",
description: "Learn how Temporal Cloud provides provable security by design - orchestrating encrypted workflows without ever accessing your sensitive data.",
- external: true,
},
]} />
diff --git a/src/components/PatternCards.tsx b/src/components/PatternCards.tsx
index 567bb81f81..c5eed3b143 100644
--- a/src/components/PatternCards.tsx
+++ b/src/components/PatternCards.tsx
@@ -1,12 +1,12 @@
import React from 'react';
import Link from '@docusaurus/Link';
import useBaseUrl from '@docusaurus/useBaseUrl';
+import { isExternalHref } from '@site/src/utils/links';
type PatternCardItem = {
href: string;
title: string;
description: string;
- external?: boolean;
icon?: string;
};
@@ -31,7 +31,8 @@ export default function PatternCards({ items, className }: PatternCardsProps) {
key={item.href}
to={item.href}
className="pattern-card"
- {...(item.external ? { target: '_blank', rel: 'noopener noreferrer' } : {})}
+ target={isExternalHref(item.href) ? '_blank' : undefined}
+ rel={isExternalHref(item.href) ? 'noopener noreferrer' : undefined}
>
{item.icon ? (
diff --git a/src/components/TemporalNavbarLink.js b/src/components/TemporalNavbarLink.js
new file mode 100644
index 0000000000..6c0aea726b
--- /dev/null
+++ b/src/components/TemporalNavbarLink.js
@@ -0,0 +1,91 @@
+import React from 'react';
+import clsx from 'clsx';
+import Link from '@docusaurus/Link';
+import useBaseUrl from '@docusaurus/useBaseUrl';
+import { isRegexpStringMatch } from '@docusaurus/theme-common';
+import IconExternalLink from '@theme/Icon/ExternalLink';
+import { isExternalHref } from '@site/src/utils/links';
+
+/**
+ * Registered as the 'default' navbar item type (see NavbarItem/ComponentTypes),
+ * replacing every plain navbar link/label item — top-level and dropdown
+ * children alike. Docusaurus's own default opens every absolute URL in a new
+ * tab and shows the external-link icon for it, including links to other
+ * temporal.io properties (learn.temporal.io, community.temporal.io, etc.).
+ * This reimplements that rendering (mirroring NavbarItem/DefaultNavbarItem +
+ * NavbarItem/NavbarNavLink) so both the tab behavior and the icon use the
+ * temporal.io-aware check instead. It's also the place to add any future
+ * top-nav item behavior, since it's ours to extend.
+ */
+export default function TemporalNavbarLink({
+ mobile = false,
+ position, // consumed only so it isn't spread onto the DOM
+ isDropdownItem = false,
+ className,
+ activeClassName,
+ activeBasePath,
+ activeBaseRegex,
+ to,
+ href,
+ label,
+ html,
+ prependBaseUrlToHref,
+ ...props
+}) {
+ const toUrl = useBaseUrl(to);
+ const activeBaseUrl = useBaseUrl(activeBasePath);
+ const normalizedHref = useBaseUrl(href, { forcePrependBaseUrl: true });
+ const external = isExternalHref(href ?? to);
+
+ const linkClassName = clsx(
+ isDropdownItem ? 'dropdown__link' : mobile ? 'menu__link' : 'navbar__item navbar__link',
+ className,
+ );
+ const resolvedActiveClassName =
+ activeClassName ?? (mobile ? 'menu__link--active' : 'navbar__link--active');
+
+ const content = html ? (
+
+ ) : (
+ <>
+ {label}
+ {external && }
+ >
+ );
+
+ const link = href ? (
+
+ {content}
+
+ ) : (
+
+ activeBaseRegex
+ ? isRegexpStringMatch(activeBaseRegex, location.pathname)
+ : location.pathname.startsWith(activeBaseUrl),
+ })}
+ {...props}
+ >
+ {content}
+
+ );
+
+ if (isDropdownItem) {
+ return
{link}
;
+ }
+ if (mobile) {
+ return
{link}
;
+ }
+ return link;
+}
diff --git a/src/components/elements/GridCard/GridCard.tsx b/src/components/elements/GridCard/GridCard.tsx
index 19ff6bfdbc..b27ec534d0 100644
--- a/src/components/elements/GridCard/GridCard.tsx
+++ b/src/components/elements/GridCard/GridCard.tsx
@@ -1,24 +1,9 @@
import React from 'react';
import Link from '@docusaurus/Link';
import clsx from 'clsx';
+import { isExternalHref } from '@site/src/utils/links';
import styles from './GridCard.module.css';
-function isExternal(href: string): boolean {
- return href.startsWith('http://') || href.startsWith('https://');
-}
-
-// A link to temporal.io itself (e.g. the Code Exchange) still opens in a new
-// tab like any other external href, but doesn't get the external-link icon —
-// it isn't "leaving Temporal" the way a partner's docs site is.
-function isOffTemporalDomain(href: string): boolean {
- try {
- const { hostname } = new URL(href);
- return hostname !== 'temporal.io' && !hostname.endsWith('.temporal.io');
- } catch {
- return true;
- }
-}
-
function ExternalLinkIcon() {
return (