diff --git a/blog/2026-02-19-typesense30docscraper.md b/blog/2026-02-19-typesense30docscraper.md
index 5c318c3..a79ddb1 100644
--- a/blog/2026-02-19-typesense30docscraper.md
+++ b/blog/2026-02-19-typesense30docscraper.md
@@ -27,3 +27,5 @@ TyKO `0.3.7` is the first version tested with Typesense 30.x+, therefore is the
**Any earlier versions combinations might lead to undefined behavior and/or potential index corruption.**
:::
+
+
diff --git a/blog/2026-02-27-release-0-4-0-rc.1.md b/blog/2026-02-27-release-0-4-0-rc.1.md
new file mode 100644
index 0000000..b4a7dcf
--- /dev/null
+++ b/blog/2026-02-27-release-0-4-0-rc.1.md
@@ -0,0 +1,17 @@
+---
+slug: release-0-4-0-rc-1
+title: 0.4.0-rc.1
+authors: [tykobot]
+tags: [release]
+---
+
+## What's Changed
+
+### 0.4.0-rc.1
+
+* 219 upgrade operator sdk by @akyriako in https://github.com/akyriako/typesense-operator/pull/240
+* 183 add support for gateway api by @akyriako in https://github.com/akyriako/typesense-operator/pull/244
+
+**Full Changelog**: https://github.com/akyriako/typesense-operator/compare/typesense-operator-0.3.8...typesense-operator-0.4.0-rc.1
+
+
diff --git a/docs/crds/examples.md b/docs/crds/examples.md
index 2b00e33..0e53365 100644
--- a/docs/crds/examples.md
+++ b/docs/crds/examples.md
@@ -473,6 +473,52 @@ To expose your Typesense cluster via an `Ingress`, certain prerequisites must al
:::
+## Gateway HttpRoutes
+
+```yaml
+apiVersion: ts.opentelekomcloud.com/v1alpha1
+kind: TypesenseCluster
+metadata:
+ name: tsc
+spec:
+ image: typesense/typesense:30.1
+ replicas: 3
+ storage:
+ storageClassName: standard
+ enableCors: true
+ corsDomains: "https://docs.example.com"
+ httpRoutes:
+ - name: public
+ parentRef:
+ name: traefik-gateway
+ namespace: kube-system
+ hostnames:
+ - typesense.docs.example.com
+ - search.docs.example.com
+ enabled: true
+ - name: private
+ parentRef:
+ name: traefik-gateway
+ namespace: kube-system
+ section: web
+ hostnames:
+ - typesense-int.docs.example.com
+ enabled: true
+ referenceGrant: true
+```
+
+:::warning
+
+**The operator does not configure or manage Gateways. Gateway setup is intentionally left out of scope because it is highly platform-specific and tightly coupled to cluster networking, security, and organizational policies. All required Gateway resources must be provisioned and maintained in advance by your platform or cluster engineering team.**
+
+To expose your Typesense cluster via a `Gateway`, certain prerequisites must already be present in your Kubernetes cluster:
+
+☑️ You will need a gateway controller present (example is using [Traefik Gateway Controller](https://doc.traefik.io/traefik/reference/routing-configuration/kubernetes/gateway-api/)).
+☑️ You will need a `GatewayClass` and a `Gateway` configured.
+☑️ You will need [cert-manager](https://cert-manager.io/) present that takes care of the TLS certiicates.
+
+:::
+
## Metrics
```yaml
diff --git a/docs/crds/index.mdx b/docs/crds/index.mdx
index b83318c..2e349db 100644
--- a/docs/crds/index.mdx
+++ b/docs/crds/index.mdx
@@ -40,7 +40,8 @@ Typesense Kubernetes Operator is controlling the lifecycle of multiple Typesense
| podsInheritStatefulSetAnnotations | propagate all `StatefulSet` annotations to `Pods` | X | false |
| serviceAnnotations | user-defined annotations | X | |
| storage | check `StorageSpec` [below](#storagespec-optional) | | |
-| ingress | check `IngressSpec` [below](#ingressspec-optional) | X | |
+| ingress | check `IngressSpec` [below](#ingressspec-deprecated) | X | |
+| httpRoutes | array of `HttpRouteSpec`; check [below](#httproutespec-optional) | X | |
| scrapers | array of `DocSearchScraperSpec`; check [below](#docsearchscraperspec-optional) | X | |
| metrics | check `MetricsSpec` [below](#metricsspec-optional) | X | |
| healthcheck | check `HealthCheckSpec` [below](#healthcheckspec-optional) | X | |
@@ -89,7 +90,28 @@ For more information about installing and configuring **JuiceFS** and **JuiceFS
:::
-### IngressSpec (optional)
+### IngressSpec (deprecated)
+
+:::warning
+
+As of **v0.4.0-rc.1**, following the events triggered by the Ingress NGINX retirement in March 2026 (see [here](https://www.kubernetes.dev/blog/2025/11/12/ingress-nginx-retirement/) the announcement of the Kubernetes SIG Network and the Security Response Committee),
+Ingress API support is deprecated in favor of the more flexible and powerful Gateway API.
+
+Although the operator will continue to support `Ingress` resources for the foreseeable future without any breaking changes,
+**no new features or maintainance updates will be made to the `Ingress` implementation**.
+
+For that reason, it is recommended to transition to use `HttpRoute` for new deployments or when updating existing ones.
+
+Additionally, bear in mind that the Kubernetes project itself recommends the following regarding Ingress API (exerpt from the [Kubernetes documentation/Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/)):
+
+"_The Kubernetes project recommends using Gateway instead of Ingress. The Ingress API has been frozen._
+
+_This means that:_
+
+_-The Ingress API is generally available, and is subject to the stability guarantees for generally available APIs. The Kubernetes project has no plans to remove Ingress from Kubernetes._
+_-The Ingress API is no longer being developed, and will have no further changes or updates made to it._"
+
+:::
| Name | Description | Optional | Default |
| ---------------------- | -------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -118,19 +140,57 @@ For more information about installing and configuring **JuiceFS** and **JuiceFS
| volumeMounts | additional mounts in the container | X | |
:::note
-This feature makes use of the existence of [cert-manager](https://cert-manager.io/) in the cluster, but **does not** actively enforce it with an error. If no clusterIssuer is specified a valid certificate must be stored in a secret and the secret name must be provided in the tlsSecretName config.
+1️⃣ This feature makes use of the existence of [cert-manager](https://cert-manager.io/) in the cluster, but **does not** actively enforce it with an error. If no clusterIssuer is specified a valid certificate must be stored in a secret and the secret name must be provided in the tlsSecretName config.
If you are targeting [Open Telekom Cloud](https://www.open-telekom-cloud.com/en), you might be interested in provisioning additionally the designated DNS solver webhook for Open Telekom Cloud. You can find it [here](https://github.com/akyriako/cert-manager-webhook-opentelekomcloud).
-:::
-:::caution
-Although in official Typesense documentation under _Production Best Practices_ -> _Configuration_ is stated:
+2️⃣ Although in official Typesense documentation under _Production Best Practices_ -> _Configuration_ is stated:
"_Typesense comes built-in with a high performance HTTP server that is used by likes of Fastly in their edge servers at scale. So Typesense can be directly exposed to incoming public-facing internet traffic, without the need to place it behind another web server like Nginx/Apache or your backend API._"
It is highly recommended, from this operator's perspective, to always expose Typesense behind a reverse proxy (using the `referer` option).
:::
+### HttpRouteSpec (optional)
+
+| Name | Description | Optional | Default |
+| -------------- | -------------------------------------------------------------------------------------- | -------- | ------------------------ |
+| name | name of the route | | |
+| enabled | enable this route | X | true |
+| parentRef | reference to the parent `Gateway`; check `GatewayParentRef` [below](#gatewayparentref) | | |
+| hostnames | array of hostnames to match for this route | | |
+| path | path to match for this route | X | / |
+| pathType | interpretation of the path matching | X | `ImplementationSpecific` |
+| labels | user-defined labels | X | |
+| annotations | user-defined annotations | X | |
+| referenceGrant | enable cross-namespace reference to the parent `Gateway` | X | false |
+
+:::warning
+
+1️⃣ **The operator does not configure or manage Gateway(s). A `Gateway` setup is intentionally left out of scope because it is highly platform-specific and tightly coupled to cluster networking, security,
+and organizational policies. All required `Gateway` resources must be provisioned and maintained in advance by your platform or cluster engineering team.**
+
+To expose your Typesense cluster via a `Gateway`, certain prerequisites must already be present in your Kubernetes cluster:
+
+🚧 You will need:
+
+- a gateway controller present (example is using [Traefik Gateway Controller](https://doc.traefik.io/traefik/reference/routing-configuration/kubernetes/gateway-api/)).
+- a `GatewayClass` and a `Gateway` configured.
+- [cert-manager](https://cert-manager.io/) to be present that takes care of the TLS certiicates.
+
+2️⃣ Activating the `HttpRoute` confiruration will automatically deactivate/ignore the `Ingress` one if it exists, but the `Ingress` resource which might be present in the cluster
+will not be automatically deleted. It can be safely deleted manually, if not needed anymore.
+
+:::
+
+#### GatewayParentRef
+
+| Name | Description | Optional | Default |
+| ----------- | -------------------------------------------------------------- | -------- | ------- |
+| name | name of the parent `Gateway` | | |
+| namespace | namespace of the parent `Gateway` | | |
+| sectionName | section of the parent `Gateway` to route to (e.g. "websecure") | X | |
+
### DocSearchScraperSpec (optional)
| Name | Description | Optional | Default |
diff --git a/docusaurus.config.ts b/docusaurus.config.ts
index 662c5dd..442e53b 100644
--- a/docusaurus.config.ts
+++ b/docusaurus.config.ts
@@ -1,5 +1,5 @@
-import {themes as prismThemes} from 'prism-react-renderer';
-import type {Config} from '@docusaurus/types';
+import { themes as prismThemes } from 'prism-react-renderer';
+import type { Config } from '@docusaurus/types';
import type * as Preset from '@docusaurus/preset-classic';
import type { Options as UmamiOptions } from '@dipakparmar/docusaurus-plugin-umami';
@@ -61,6 +61,8 @@ const config: Config = {
onInlineTags: 'warn',
onInlineAuthors: 'warn',
onUntruncatedBlogPosts: 'warn',
+ blogSidebarTitle: 'All posts',
+ blogSidebarCount: 'ALL',
},
theme: {
customCss: './src/css/custom.css',
@@ -85,13 +87,13 @@ const config: Config = {
position: 'left',
label: 'Docs',
},
- {to: '/blog', label: 'Releases', position: 'left'},
+ { to: '/blog', label: 'Releases', position: 'left' },
// {
// type: 'docsVersionDropdown',
// position: 'right'
// },
- {
- href: 'https://github.com/akyriako/typesense-operator',
+ {
+ href: 'https://github.com/akyriako/typesense-operator',
position: 'right',
className: 'navbar--github-link',
"aria-label": 'GitHub',
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index 77b42e0..a638a9d 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -3,7 +3,7 @@ import Layout from "@theme/Layout";
import Link from "@docusaurus/Link";
import useBaseUrl from '@docusaurus/useBaseUrl';
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
-import { BarChart3, Lock, HeartPulse, Rocket, CircleFadingArrowUp, Ship, Cable } from "lucide-react";
+import { BarChart3, Lock, HeartPulse, Rocket, CircleFadingArrowUp, Ship, Cable, HandPlatter, Archive } from "lucide-react";
export default function Home(): JSX.Element {
const { siteConfig } = useDocusaurusContext();
@@ -33,7 +33,7 @@ export default function Home(): JSX.Element {
{s.desc}
- Learn more -> + Learn more -{">"} @@ -151,24 +151,24 @@ export default function Home(): JSX.Element { const features = [ { - title: "Self‑healing clusters", + title: "Self-healing clusters", desc: "Automated failover, quorum recovery, and raft re-evaluation keep your Typesense clusters healthy without any manual intervention.", icon: