diff --git a/assets/styles/layouts/_api-hugo-native.scss b/assets/styles/layouts/_api-hugo-native.scss
new file mode 100644
index 000000000..2b26bf16a
--- /dev/null
+++ b/assets/styles/layouts/_api-hugo-native.scss
@@ -0,0 +1,598 @@
+// Hugo-Native API Documentation Styles
+// Styled after docusaurus-openapi aesthetic with clean, readable layouts
+
+// Variables
+$api-border-radius: 6px;
+$api-spacing-sm: 0.5rem;
+$api-spacing-md: 1rem;
+$api-spacing-lg: 1.5rem;
+$api-spacing-xl: 2rem;
+
+// Method colors (matching existing theme)
+$method-get: #00A3FF;
+$method-post: #34BB55;
+$method-put: #FFB94A;
+$method-delete: #F95F53;
+$method-patch: #9b2aff;
+
+// Status code colors
+$status-success: #34BB55;
+$status-redirect: #FFB94A;
+$status-client-error: #F95F53;
+$status-server-error: #9b2aff;
+
+// ============================================
+// Operation Block
+// ============================================
+
+.api-hugo-native {
+ width: 100%;
+}
+
+.api-operation {
+ margin-bottom: $api-spacing-xl;
+ padding: $api-spacing-lg;
+ background: var(--article-bg, #fff);
+ border: 1px solid var(--article-border, #e8e8f0);
+ border-radius: $api-border-radius;
+
+ &:target {
+ animation: highlight-operation 1.5s ease-out;
+ }
+}
+
+@keyframes highlight-operation {
+ 0% {
+ box-shadow: 0 0 0 4px rgba($method-get, 0.3);
+ }
+ 100% {
+ box-shadow: none;
+ }
+}
+
+// Operation Header
+.api-operation-header {
+ margin-bottom: $api-spacing-md;
+}
+
+.api-operation-endpoint {
+ display: flex;
+ align-items: center;
+ gap: $api-spacing-sm;
+ margin-bottom: $api-spacing-sm;
+}
+
+.api-method {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0.25rem 0.5rem;
+ font-size: 0.75rem;
+ font-weight: 600;
+ text-transform: uppercase;
+ border-radius: 4px;
+ color: #fff;
+
+ &--get { background-color: $method-get; }
+ &--post { background-color: $method-post; }
+ &--put { background-color: $method-put; }
+ &--delete { background-color: $method-delete; }
+ &--patch { background-color: $method-patch; }
+}
+
+.api-path {
+ font-family: var(--mono-font, 'IBM Plex Mono', monospace);
+ font-size: 0.95rem;
+ color: var(--article-text, #2b2b2b);
+ background: var(--code-bg, #f5f5f5);
+ padding: 0.25rem 0.5rem;
+ border-radius: 4px;
+}
+
+.api-operation-summary {
+ margin: 0;
+ font-size: 1.25rem;
+ font-weight: 600;
+ color: var(--article-heading, #2b2b2b);
+}
+
+.api-operation-description {
+ margin: $api-spacing-md 0;
+ color: var(--article-text, #545667);
+ line-height: 1.6;
+
+ p:last-child {
+ margin-bottom: 0;
+ }
+}
+
+// ============================================
+// Section Titles
+// ============================================
+
+.api-section-title {
+ display: flex;
+ align-items: center;
+ gap: $api-spacing-sm;
+ margin: $api-spacing-lg 0 $api-spacing-md;
+ padding-bottom: $api-spacing-sm;
+ font-size: 1rem;
+ font-weight: 600;
+ color: var(--article-heading, #2b2b2b);
+ border-bottom: 1px solid var(--article-border, #e8e8f0);
+}
+
+// ============================================
+// Parameters Section
+// ============================================
+
+.api-parameters {
+ margin: $api-spacing-lg 0;
+}
+
+.api-param-group {
+ margin-bottom: $api-spacing-md;
+}
+
+.api-param-group-title {
+ margin: $api-spacing-sm 0;
+ font-size: 0.85rem;
+ font-weight: 500;
+ color: var(--article-text-muted, #777);
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+}
+
+.api-param-list {
+ border: 1px solid var(--article-border, #e8e8f0);
+ border-radius: $api-border-radius;
+ overflow: hidden;
+}
+
+.api-param-row {
+ padding: $api-spacing-md;
+ border-bottom: 1px solid var(--article-border, #e8e8f0);
+ background: var(--article-bg, #fff);
+
+ &:last-child {
+ border-bottom: none;
+ }
+
+ &:hover {
+ background: var(--article-bg-hover, #f9f9fb);
+ }
+
+ &--required {
+ background: rgba($method-post, 0.03);
+
+ &:hover {
+ background: rgba($method-post, 0.06);
+ }
+ }
+}
+
+.api-param-name-line {
+ display: flex;
+ align-items: center;
+ gap: $api-spacing-sm;
+ margin-bottom: 0.25rem;
+}
+
+.api-param-name {
+ font-family: var(--mono-font, 'IBM Plex Mono', monospace);
+ font-size: 0.9rem;
+ font-weight: 600;
+ color: var(--article-heading, #2b2b2b);
+}
+
+.api-param-type {
+ font-size: 0.8rem;
+ color: var(--article-text-muted, #777);
+}
+
+.api-param-description {
+ margin-top: 0.25rem;
+ font-size: 0.9rem;
+ color: var(--article-text, #545667);
+ line-height: 1.5;
+
+ p {
+ margin: 0;
+ }
+}
+
+.api-param-enum,
+.api-param-default {
+ margin-top: 0.5rem;
+ font-size: 0.85rem;
+}
+
+.api-param-enum-label,
+.api-param-default-label {
+ color: var(--article-text-muted, #777);
+}
+
+.api-param-enum-value,
+.api-param-default-value {
+ font-family: var(--mono-font, 'IBM Plex Mono', monospace);
+ font-size: 0.8rem;
+ background: var(--code-bg, #f5f5f5);
+ padding: 0.125rem 0.375rem;
+ border-radius: 3px;
+}
+
+// ============================================
+// Badges
+// ============================================
+
+.api-badge {
+ display: inline-flex;
+ align-items: center;
+ padding: 0.125rem 0.375rem;
+ font-size: 0.7rem;
+ font-weight: 600;
+ text-transform: uppercase;
+ letter-spacing: 0.03em;
+ border-radius: 3px;
+
+ &--required {
+ background: rgba($method-delete, 0.1);
+ color: $method-delete;
+ }
+}
+
+// ============================================
+// Request Body Section
+// ============================================
+
+.api-request-body {
+ margin: $api-spacing-lg 0;
+}
+
+.api-request-body-description {
+ margin: $api-spacing-sm 0;
+ color: var(--article-text, #545667);
+
+ p:last-child {
+ margin-bottom: 0;
+ }
+}
+
+.api-content-type {
+ margin: $api-spacing-sm 0;
+ font-size: 0.85rem;
+
+ code {
+ font-family: var(--mono-font, 'IBM Plex Mono', monospace);
+ background: var(--code-bg, #f5f5f5);
+ padding: 0.125rem 0.375rem;
+ border-radius: 3px;
+ }
+}
+
+.api-content-type-label {
+ color: var(--article-text-muted, #777);
+}
+
+// ============================================
+// Schema Section
+// ============================================
+
+.api-schema {
+ margin: $api-spacing-md 0;
+
+ &--nested {
+ margin-left: $api-spacing-lg;
+ padding-left: $api-spacing-md;
+ border-left: 2px solid var(--article-border, #e8e8f0);
+ }
+}
+
+.api-schema-properties {
+ border: 1px solid var(--article-border, #e8e8f0);
+ border-radius: $api-border-radius;
+ overflow: hidden;
+}
+
+.api-schema-property {
+ padding: $api-spacing-md;
+ border-bottom: 1px solid var(--article-border, #e8e8f0);
+ background: var(--article-bg, #fff);
+
+ &:last-child {
+ border-bottom: none;
+ }
+
+ &:hover {
+ background: var(--article-bg-hover, #f9f9fb);
+ }
+
+ &--required {
+ .api-schema-property-name {
+ &::after {
+ content: '*';
+ color: $method-delete;
+ margin-left: 0.25rem;
+ }
+ }
+ }
+}
+
+.api-schema-property-header {
+ display: flex;
+ align-items: center;
+ gap: $api-spacing-sm;
+ margin-bottom: 0.25rem;
+}
+
+.api-schema-property-name {
+ font-family: var(--mono-font, 'IBM Plex Mono', monospace);
+ font-size: 0.9rem;
+ font-weight: 600;
+ color: var(--article-heading, #2b2b2b);
+}
+
+.api-schema-property-type {
+ font-size: 0.8rem;
+ color: var(--article-text-muted, #777);
+}
+
+.api-schema-property-description {
+ margin-top: 0.25rem;
+ font-size: 0.9rem;
+ color: var(--article-text, #545667);
+ line-height: 1.5;
+
+ p {
+ margin: 0;
+ }
+}
+
+.api-schema-property-enum,
+.api-schema-property-default,
+.api-schema-property-example {
+ margin-top: 0.5rem;
+ font-size: 0.85rem;
+}
+
+.api-enum-label,
+.api-default-label,
+.api-example-label {
+ color: var(--article-text-muted, #777);
+}
+
+.api-enum-value,
+.api-default-value,
+.api-example-value {
+ font-family: var(--mono-font, 'IBM Plex Mono', monospace);
+ font-size: 0.8rem;
+ background: var(--code-bg, #f5f5f5);
+ padding: 0.125rem 0.375rem;
+ border-radius: 3px;
+}
+
+// Schema Example Block
+.api-schema-example {
+ margin-top: $api-spacing-md;
+ padding: $api-spacing-md;
+ background: var(--code-bg, #f5f5f5);
+ border-radius: $api-border-radius;
+}
+
+.api-schema-example-title {
+ margin: 0 0 $api-spacing-sm;
+ font-size: 0.85rem;
+ font-weight: 600;
+ color: var(--article-text-muted, #777);
+}
+
+.api-schema-example-code {
+ margin: 0;
+ padding: 0;
+ background: transparent;
+ overflow-x: auto;
+
+ code {
+ font-family: var(--mono-font, 'IBM Plex Mono', monospace);
+ font-size: 0.85rem;
+ }
+}
+
+// ============================================
+// Responses Section
+// ============================================
+
+.api-responses {
+ margin: $api-spacing-lg 0;
+}
+
+.api-response-list {
+ display: flex;
+ flex-direction: column;
+ gap: $api-spacing-sm;
+}
+
+.api-response {
+ border: 1px solid var(--article-border, #e8e8f0);
+ border-radius: $api-border-radius;
+ overflow: hidden;
+}
+
+.api-response-header {
+ display: flex;
+ align-items: center;
+ gap: $api-spacing-sm;
+ padding: $api-spacing-sm $api-spacing-md;
+ background: var(--article-bg-alt, #f9f9fb);
+}
+
+.api-response-status {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 3rem;
+ padding: 0.25rem 0.5rem;
+ font-size: 0.8rem;
+ font-weight: 600;
+ border-radius: 4px;
+ color: #fff;
+
+ &--success { background-color: $status-success; }
+ &--redirect { background-color: $status-redirect; }
+ &--client-error { background-color: $status-client-error; }
+ &--server-error { background-color: $status-server-error; }
+ &--info { background-color: var(--article-text-muted, #777); }
+}
+
+.api-response-description {
+ font-size: 0.9rem;
+ color: var(--article-text, #545667);
+}
+
+.api-response-body {
+ padding: $api-spacing-md;
+ border-top: 1px solid var(--article-border, #e8e8f0);
+}
+
+// ============================================
+// Tag Overview
+// ============================================
+
+.api-tag-overview {
+ margin-bottom: $api-spacing-xl;
+ padding-bottom: $api-spacing-lg;
+ border-bottom: 1px solid var(--article-border, #e8e8f0);
+}
+
+.api-tag-description {
+ color: var(--article-text, #545667);
+ line-height: 1.7;
+
+ h4, h5 {
+ margin-top: $api-spacing-lg;
+ margin-bottom: $api-spacing-sm;
+ color: var(--article-heading, #2b2b2b);
+ }
+
+ ul, ol {
+ padding-left: $api-spacing-lg;
+ }
+
+ a {
+ color: var(--link-color, #00A3FF);
+
+ &:hover {
+ text-decoration: underline;
+ }
+ }
+}
+
+// ============================================
+// Related Guides Section
+// ============================================
+
+.api-related-guides {
+ margin-top: $api-spacing-xl;
+ padding-top: $api-spacing-lg;
+ border-top: 1px solid var(--article-border, #e8e8f0);
+}
+
+.api-related-title {
+ margin: 0 0 $api-spacing-md;
+ font-size: 1rem;
+ font-weight: 600;
+ color: var(--article-heading, #2b2b2b);
+}
+
+.api-related-list {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+
+ li {
+ margin-bottom: $api-spacing-sm;
+ }
+
+ a {
+ color: var(--link-color, #00A3FF);
+ text-decoration: none;
+
+ &:hover {
+ text-decoration: underline;
+ }
+ }
+}
+
+// ============================================
+// Dark Mode Overrides
+// ============================================
+
+[data-theme='dark'],
+html:has(link[title='dark-theme']:not([disabled])) {
+ .api-operation {
+ background: var(--article-bg, #1a1a2a);
+ border-color: var(--article-border, #2a2a3a);
+ }
+
+ .api-related-guides {
+ border-color: var(--article-border, #2a2a3a);
+ }
+
+ .api-related-title {
+ color: var(--article-heading, #e0e0e0);
+ }
+
+ .api-path {
+ background: var(--code-bg, #252535);
+ color: var(--article-text, #d4d7dd);
+ }
+
+ .api-param-row,
+ .api-schema-property {
+ background: var(--article-bg, #1a1a2a);
+
+ &:hover {
+ background: var(--article-bg-hover, #252535);
+ }
+ }
+
+ .api-param-enum-value,
+ .api-param-default-value,
+ .api-enum-value,
+ .api-default-value,
+ .api-example-value {
+ background: var(--code-bg, #252535);
+ }
+
+ .api-schema-example {
+ background: var(--code-bg, #252535);
+ }
+
+ .api-response-header {
+ background: var(--article-bg-alt, #252535);
+ }
+}
+
+// ============================================
+// Responsive Adjustments
+// ============================================
+
+@media (max-width: 768px) {
+ .api-operation {
+ padding: $api-spacing-md;
+ }
+
+ .api-operation-endpoint {
+ flex-wrap: wrap;
+ }
+
+ .api-path {
+ font-size: 0.85rem;
+ word-break: break-all;
+ }
+
+ .api-param-name-line,
+ .api-schema-property-header {
+ flex-wrap: wrap;
+ }
+}
diff --git a/assets/styles/styles-default.scss b/assets/styles/styles-default.scss
index ce318f720..589160164 100644
--- a/assets/styles/styles-default.scss
+++ b/assets/styles/styles-default.scss
@@ -34,7 +34,8 @@
"layouts/code-controls",
"layouts/v3-wayfinding",
"layouts/api-layout",
- "layouts/api-security-schemes";
+ "layouts/api-security-schemes",
+ "layouts/api-hugo-native";
// Import Components
@import "components/influxdb-version-detector",
diff --git a/layouts/api/list.html b/layouts/api/list.html
index f36746f6b..b12dbc965 100644
--- a/layouts/api/list.html
+++ b/layouts/api/list.html
@@ -124,10 +124,20 @@ param) - shows RapiDoc with all operations for the tag For conceptual pages
{{/* Hugo page content if any (for custom intro content) */}}
{{ with .Content }}
- {{ end }} {{/* RapiDoc renders all operations for this tag */}} {{ with
- .Params.staticFilePath }}
+ {{ end }}
+
+ {{/* Choose rendering mode: Hugo-native (POC) or RapiDoc (default) */}}
+ {{ $useHugoNative := .Params.useHugoNative | default false }}
+
+ {{ with .Params.staticFilePath }}
- {{ partial "api/rapidoc-tag.html" $ }}
+ {{ if $useHugoNative }}
+ {{/* Hugo-Native rendering (docusaurus-openapi style) */}}
+ {{ partial "api/hugo-native/tag-renderer.html" $ }}
+ {{ else }}
+ {{/* RapiDoc rendering (current default) */}}
+ {{ partial "api/rapidoc-tag.html" $ }}
+ {{ end }}
{{ end }} {{ end }} {{ end }} {{ partial "article/related.html" . }}
diff --git a/layouts/partials/api/hugo-native/operation.html b/layouts/partials/api/hugo-native/operation.html
new file mode 100644
index 000000000..72ce380ce
--- /dev/null
+++ b/layouts/partials/api/hugo-native/operation.html
@@ -0,0 +1,61 @@
+{{/*
+ Hugo-Native Operation Renderer
+
+ Renders a single API operation with parameters, request body, and responses.
+ Styled to match docusaurus-openapi aesthetic.
+
+ Params:
+ - operation: Map with method, path, summary, operationId
+ - spec: The full OpenAPI spec object
+ - context: The page context for URL generation
+*/}}
+
+{{ $operation := .operation }}
+{{ $spec := .spec }}
+{{ $method := lower $operation.method }}
+{{ $path := $operation.path }}
+{{ $operationId := $operation.operationId }}
+
+{{/* Find the operation definition in the spec */}}
+{{ $pathDef := index $spec.paths $path }}
+{{ $opDef := dict }}
+{{ if $pathDef }}
+ {{ $opDef = index $pathDef $method | default dict }}
+{{ end }}
+
+{{/* Generate anchor ID matching existing TOC format */}}
+{{ $anchorId := printf "%s-%s" $method $path }}
+
+
+ {{/* Operation Header */}}
+
+
+ {{/* Operation Description */}}
+ {{ with $opDef.description }}
+
+ {{ . | markdownify }}
+
+ {{ end }}
+
+ {{/* Parameters Section */}}
+ {{ $params := $opDef.parameters | default slice }}
+ {{ if gt (len $params) 0 }}
+ {{ partial "api/hugo-native/parameters.html" (dict "parameters" $params "spec" $spec) }}
+ {{ end }}
+
+ {{/* Request Body Section */}}
+ {{ with $opDef.requestBody }}
+ {{ partial "api/hugo-native/request-body.html" (dict "requestBody" . "spec" $spec) }}
+ {{ end }}
+
+ {{/* Responses Section */}}
+ {{ with $opDef.responses }}
+ {{ partial "api/hugo-native/responses.html" (dict "responses" . "spec" $spec) }}
+ {{ end }}
+
diff --git a/layouts/partials/api/hugo-native/parameter-row.html b/layouts/partials/api/hugo-native/parameter-row.html
new file mode 100644
index 000000000..5f34125a9
--- /dev/null
+++ b/layouts/partials/api/hugo-native/parameter-row.html
@@ -0,0 +1,65 @@
+{{/*
+ Hugo-Native Parameter Row Renderer
+
+ Renders a single parameter with name, type, required badge, and description.
+
+ Params:
+ - param: Parameter object with name, schema, required, description
+ - spec: The full OpenAPI spec object for resolving schema $ref
+*/}}
+
+{{ $param := .param }}
+{{ $spec := .spec }}
+
+{{ $name := $param.name }}
+{{ $required := $param.required | default false }}
+{{ $description := $param.description | default "" }}
+
+{{/* Resolve schema type */}}
+{{ $schema := $param.schema | default dict }}
+{{ $type := $schema.type | default "string" }}
+{{ $format := $schema.format | default "" }}
+{{ $enum := $schema.enum | default slice }}
+{{ $default := $schema.default }}
+
+{{/* Build type display string */}}
+{{ $typeDisplay := $type }}
+{{ if $format }}
+ {{ $typeDisplay = printf "%s <%s>" $type $format }}
+{{ end }}
+
+
+
+
+ {{ $name }}
+ {{ if $required }}
+ required
+ {{ end }}
+ {{ $typeDisplay }}
+
+
+ {{ if $description }}
+
+ {{ $description | markdownify }}
+
+ {{ end }}
+
+ {{/* Show enum values if present */}}
+ {{ if gt (len $enum) 0 }}
+
+ Allowed values:
+ {{ range $i, $val := $enum }}
+ {{ if $i }}, {{ end }}{{ $val }}
+ {{ end }}
+
+ {{ end }}
+
+ {{/* Show default value if present */}}
+ {{ if $default }}
+
+ Default:
+ {{ $default }}
+
+ {{ end }}
+
+
diff --git a/layouts/partials/api/hugo-native/parameters.html b/layouts/partials/api/hugo-native/parameters.html
new file mode 100644
index 000000000..43ad2efff
--- /dev/null
+++ b/layouts/partials/api/hugo-native/parameters.html
@@ -0,0 +1,85 @@
+{{/*
+ Hugo-Native Parameters Renderer
+
+ Renders a table of API operation parameters (query, path, header).
+ Resolves $ref references to component parameters.
+
+ Params:
+ - parameters: Array of parameter objects
+ - spec: The full OpenAPI spec object for resolving $ref
+*/}}
+
+{{ $parameters := .parameters }}
+{{ $spec := .spec }}
+
+{{/* Resolve $ref parameters and group by location */}}
+{{ $queryParams := slice }}
+{{ $pathParams := slice }}
+{{ $headerParams := slice }}
+
+{{ range $parameters }}
+ {{ $param := . }}
+
+ {{/* Resolve $ref if present */}}
+ {{ if isset . "$ref" }}
+ {{ $refPath := index . "$ref" }}
+ {{/* Parse ref like "#/components/parameters/db" */}}
+ {{ $refParts := split $refPath "/" }}
+ {{ if ge (len $refParts) 4 }}
+ {{ $paramName := index $refParts 3 }}
+ {{ with index $spec.components.parameters $paramName }}
+ {{ $param = . }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+
+ {{/* Group by 'in' location */}}
+ {{ $location := $param.in | default "query" }}
+ {{ if eq $location "query" }}
+ {{ $queryParams = $queryParams | append $param }}
+ {{ else if eq $location "path" }}
+ {{ $pathParams = $pathParams | append $param }}
+ {{ else if eq $location "header" }}
+ {{ $headerParams = $headerParams | append $param }}
+ {{ end }}
+{{ end }}
+
+
+
Parameters
+
+ {{/* Path Parameters */}}
+ {{ if gt (len $pathParams) 0 }}
+
+
Path parameters
+
+ {{ range $pathParams }}
+ {{ partial "api/hugo-native/parameter-row.html" (dict "param" . "spec" $spec) }}
+ {{ end }}
+
+
+ {{ end }}
+
+ {{/* Query Parameters */}}
+ {{ if gt (len $queryParams) 0 }}
+
+
Query parameters
+
+ {{ range $queryParams }}
+ {{ partial "api/hugo-native/parameter-row.html" (dict "param" . "spec" $spec) }}
+ {{ end }}
+
+
+ {{ end }}
+
+ {{/* Header Parameters */}}
+ {{ if gt (len $headerParams) 0 }}
+
+
Header parameters
+
+ {{ range $headerParams }}
+ {{ partial "api/hugo-native/parameter-row.html" (dict "param" . "spec" $spec) }}
+ {{ end }}
+
+
+ {{ end }}
+
diff --git a/layouts/partials/api/hugo-native/request-body.html b/layouts/partials/api/hugo-native/request-body.html
new file mode 100644
index 000000000..f90df93f1
--- /dev/null
+++ b/layouts/partials/api/hugo-native/request-body.html
@@ -0,0 +1,60 @@
+{{/*
+ Hugo-Native Request Body Renderer
+
+ Renders the request body section including schema properties.
+
+ Params:
+ - requestBody: OpenAPI requestBody object
+ - spec: The full OpenAPI spec object for resolving $ref
+*/}}
+
+{{ $requestBody := .requestBody }}
+{{ $spec := .spec }}
+
+{{ $required := $requestBody.required | default false }}
+{{ $description := $requestBody.description | default "" }}
+
+{{/* Get content schema - typically application/json */}}
+{{ $content := $requestBody.content | default dict }}
+{{ $jsonContent := index $content "application/json" | default dict }}
+{{ $schema := $jsonContent.schema | default dict }}
+
+{{/* Resolve $ref if present */}}
+{{ $resolvedSchema := $schema }}
+{{ if isset $schema "$ref" }}
+ {{ $refPath := index $schema "$ref" }}
+ {{/* Parse ref like "#/components/schemas/DistinctCacheCreateRequest" */}}
+ {{ $refParts := split $refPath "/" }}
+ {{ if ge (len $refParts) 4 }}
+ {{ $schemaName := index $refParts 3 }}
+ {{ with index $spec.components.schemas $schemaName }}
+ {{ $resolvedSchema = . }}
+ {{ end }}
+ {{ end }}
+{{ end }}
+
+
+
+ Request body
+ {{ if $required }}
+ required
+ {{ end }}
+
+
+ {{ if $description }}
+
+ {{ $description | markdownify }}
+
+ {{ end }}
+
+ {{/* Content type indicator */}}
+
+ Content-Type:
+ application/json
+
+
+ {{/* Render schema properties */}}
+ {{ with $resolvedSchema }}
+ {{ partial "api/hugo-native/schema.html" (dict "schema" . "spec" $spec "level" 0) }}
+ {{ end }}
+
diff --git a/layouts/partials/api/hugo-native/responses.html b/layouts/partials/api/hugo-native/responses.html
new file mode 100644
index 000000000..8f66a7cd8
--- /dev/null
+++ b/layouts/partials/api/hugo-native/responses.html
@@ -0,0 +1,79 @@
+{{/*
+ Hugo-Native Responses Renderer
+
+ Renders the responses section for an API operation.
+ Shows status codes, descriptions, and response schemas.
+
+ Params:
+ - responses: Map of status codes to response objects
+ - spec: The full OpenAPI spec object for resolving $ref
+*/}}
+
+{{ $responses := .responses }}
+{{ $spec := .spec }}
+
+
+
Responses
+
+
+ {{ range $statusCode, $response := $responses }}
+ {{/* Resolve $ref if present */}}
+ {{ $resolvedResponse := $response }}
+ {{ if isset $response "$ref" }}
+ {{ $refPath := index $response "$ref" }}
+ {{ $refParts := split $refPath "/" }}
+ {{ if ge (len $refParts) 4 }}
+ {{ $responseName := index $refParts 3 }}
+ {{ with index $spec.components.responses $responseName }}
+ {{ $resolvedResponse = . }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+
+ {{ $description := $resolvedResponse.description | default "" }}
+ {{ $content := $resolvedResponse.content | default dict }}
+
+ {{/* Determine status category for styling */}}
+ {{ $statusCategory := "info" }}
+ {{ if hasPrefix $statusCode "2" }}
+ {{ $statusCategory = "success" }}
+ {{ else if hasPrefix $statusCode "3" }}
+ {{ $statusCategory = "redirect" }}
+ {{ else if hasPrefix $statusCode "4" }}
+ {{ $statusCategory = "client-error" }}
+ {{ else if hasPrefix $statusCode "5" }}
+ {{ $statusCategory = "server-error" }}
+ {{ end }}
+
+
+
+
+ {{/* Response body schema if present */}}
+ {{ with $content }}
+ {{ $jsonContent := index . "application/json" | default dict }}
+ {{ with $jsonContent.schema }}
+ {{/* Resolve schema $ref if present */}}
+ {{ $resolvedSchema := . }}
+ {{ if isset . "$ref" }}
+ {{ $refPath := index . "$ref" }}
+ {{ $refParts := split $refPath "/" }}
+ {{ if ge (len $refParts) 4 }}
+ {{ $schemaName := index $refParts 3 }}
+ {{ with index $spec.components.schemas $schemaName }}
+ {{ $resolvedSchema = . }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+
+
+ {{ partial "api/hugo-native/schema.html" (dict "schema" $resolvedSchema "spec" $spec "level" 0) }}
+
+ {{ end }}
+ {{ end }}
+
+ {{ end }}
+
+
diff --git a/layouts/partials/api/hugo-native/schema.html b/layouts/partials/api/hugo-native/schema.html
new file mode 100644
index 000000000..6d2f2c06d
--- /dev/null
+++ b/layouts/partials/api/hugo-native/schema.html
@@ -0,0 +1,117 @@
+{{/*
+ Hugo-Native Schema Renderer
+
+ Renders a JSON schema as a property table with nested object support.
+ Similar to docusaurus-openapi's schema tables.
+
+ Params:
+ - schema: OpenAPI schema object
+ - spec: The full OpenAPI spec object for resolving $ref
+ - level: Nesting level (0 = root)
+*/}}
+
+{{ $schema := .schema }}
+{{ $spec := .spec }}
+{{ $level := .level | default 0 }}
+
+{{ $type := $schema.type | default "object" }}
+{{ $properties := $schema.properties | default dict }}
+{{ $required := $schema.required | default slice }}
+{{ $example := $schema.example }}
+
+{{/* Convert required slice to map for easy lookup */}}
+{{ $requiredMap := dict }}
+{{ range $required }}
+ {{ $requiredMap = merge $requiredMap (dict . true) }}
+{{ end }}
+
+
+ {{ if gt (len $properties) 0 }}
+
+ {{ range $propName, $propSchema := $properties }}
+ {{ $isRequired := index $requiredMap $propName | default false }}
+ {{ $propType := $propSchema.type | default "string" }}
+ {{ $propDescription := $propSchema.description | default "" }}
+ {{ $propFormat := $propSchema.format | default "" }}
+ {{ $propEnum := $propSchema.enum | default slice }}
+ {{ $propDefault := $propSchema.default }}
+ {{ $propExample := $propSchema.example }}
+
+ {{/* Build type display */}}
+ {{ $typeDisplay := $propType }}
+ {{ if eq $propType "array" }}
+ {{ $itemsType := "object" }}
+ {{ with $propSchema.items }}
+ {{ $itemsType = .type | default "object" }}
+ {{ end }}
+ {{ $typeDisplay = printf "%s[]" $itemsType }}
+ {{ else if $propFormat }}
+ {{ $typeDisplay = printf "%s <%s>" $propType $propFormat }}
+ {{ end }}
+
+
+
+
+ {{ if $propDescription }}
+
+ {{ $propDescription | markdownify }}
+
+ {{ end }}
+
+ {{/* Enum values */}}
+ {{ if gt (len $propEnum) 0 }}
+
+ Allowed:
+ {{ range $i, $val := $propEnum }}
+ {{ if $i }}, {{ end }}{{ $val }}
+ {{ end }}
+
+ {{ end }}
+
+ {{/* Default value */}}
+ {{ if $propDefault }}
+
+ Default:
+ {{ $propDefault }}
+
+ {{ end }}
+
+ {{/* Example value */}}
+ {{ if $propExample }}
+
+ Example:
+ {{ jsonify $propExample }}
+
+ {{ end }}
+
+ {{/* Nested object/array rendering (limit depth to prevent infinite loops) */}}
+ {{ if and (eq $propType "object") (lt $level 2) }}
+ {{ with $propSchema.properties }}
+ {{ partial "api/hugo-native/schema.html" (dict "schema" $propSchema "spec" $spec "level" (add $level 1)) }}
+ {{ end }}
+ {{ else if and (eq $propType "array") (lt $level 2) }}
+ {{ with $propSchema.items }}
+ {{ if isset . "properties" }}
+ {{ partial "api/hugo-native/schema.html" (dict "schema" . "spec" $spec "level" (add $level 1)) }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+
+ {{ end }}
+
+ {{ end }}
+
+ {{/* Show example at schema level */}}
+ {{ if and $example (eq $level 0) }}
+
+
Example
+
{{ jsonify (dict "indent" " ") $example }}
+
+ {{ end }}
+
diff --git a/layouts/partials/api/hugo-native/tag-renderer.html b/layouts/partials/api/hugo-native/tag-renderer.html
new file mode 100644
index 000000000..ebd4a94e2
--- /dev/null
+++ b/layouts/partials/api/hugo-native/tag-renderer.html
@@ -0,0 +1,83 @@
+{{/*
+ Hugo-Native Tag Page Renderer
+
+ Renders all operations for a tag page using Hugo templates instead of RapiDoc.
+ Parses the OpenAPI spec file and renders each operation natively.
+
+ Required page params:
+ - staticFilePath: Path to the OpenAPI specification file (YAML)
+ - operations: Array of operation metadata from frontmatter
+
+ Usage:
+ {{ partial "api/hugo-native/tag-renderer.html" . }}
+*/}}
+
+{{ $page := . }}
+{{ $specPath := .Params.staticFilePath }}
+{{ $operations := .Params.operations | default slice }}
+
+{{/* Load and parse the OpenAPI spec from static/ directory */}}
+{{ $spec := dict }}
+{{ if $specPath }}
+ {{/* Build path to static file (staticFilePath has leading slash, e.g. /openapi/...) */}}
+ {{ $staticFile := printf "static%s" $specPath }}
+
+ {{/* Use os.ReadFile (Hugo 0.121+) to read from static directory */}}
+ {{ with os.ReadFile $staticFile }}
+ {{ $spec = . | transform.Unmarshal }}
+ {{ else }}
+ {{/* Fallback: try unmounted resources (for assets mount configuration) */}}
+ {{ $cleanPath := strings.TrimPrefix "/" $specPath }}
+ {{ with resources.Get $cleanPath }}
+ {{ $spec = .Content | transform.Unmarshal }}
+ {{ end }}
+ {{ end }}
+{{ end }}
+
+{{/* Tag description and related links from spec */}}
+{{ $tagDescription := "" }}
+{{ $tagRelated := slice }}
+{{ $tagName := .Params.tag | default "" }}
+{{ range $spec.tags }}
+ {{ if eq .name $tagName }}
+ {{ $tagDescription = .description | default "" }}
+ {{/* Extract x-influxdata-related from the tag */}}
+ {{ with index . "x-influxdata-related" }}
+ {{ $tagRelated = . }}
+ {{ end }}
+ {{ end }}
+{{ end }}
+
+
+ {{/* Tag Overview/Description */}}
+ {{ if $tagDescription }}
+
+
+ {{ $tagDescription | markdownify }}
+
+
+ {{ end }}
+
+ {{/* Operations List */}}
+
+ {{ range $operations }}
+ {{ partial "api/hugo-native/operation.html" (dict
+ "operation" .
+ "spec" $spec
+ "context" $page
+ ) }}
+ {{ end }}
+
+
+ {{/* Related Guides - displayed at bottom like standard page template */}}
+ {{ if gt (len $tagRelated) 0 }}
+
+ {{ end }}
+