zuplo 6.70.71 → 6.71.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/docs/analytics/access-and-entitlements.md +1 -1
  2. package/docs/analytics/overview.md +12 -8
  3. package/docs/analytics/reference/metrics-glossary.md +3 -3
  4. package/docs/analytics/shared-controls.md +12 -11
  5. package/docs/analytics/tabs/agents.md +14 -14
  6. package/docs/analytics/tabs/consumers.md +6 -6
  7. package/docs/analytics/tabs/graphql.md +5 -4
  8. package/docs/analytics/tabs/mcp.md +7 -7
  9. package/docs/analytics/tabs/origins.md +11 -10
  10. package/docs/analytics/tabs/requests.md +6 -5
  11. package/docs/articles/accounts/enterprise-sso.mdx +8 -6
  12. package/docs/articles/api-key-administration.mdx +4 -0
  13. package/docs/articles/bypass-policy-for-testing.mdx +4 -0
  14. package/docs/articles/environment-variables.mdx +5 -1
  15. package/docs/articles/environments.mdx +2 -2
  16. package/docs/articles/graphql.mdx +125 -74
  17. package/docs/articles/mcp-quickstart-local.mdx +2 -1
  18. package/docs/articles/mcp-quickstart.mdx +6 -1
  19. package/docs/articles/multiple-auth-policies.mdx +2 -2
  20. package/docs/articles/openapi.mdx +6 -1
  21. package/docs/articles/rename-or-move-project.mdx +4 -0
  22. package/docs/articles/securing-your-backend.mdx +11 -3
  23. package/docs/articles/source-control-setup-github.mdx +4 -0
  24. package/docs/articles/troubleshooting-slow-responses.mdx +2 -2
  25. package/docs/articles/troubleshooting.md +3 -3
  26. package/docs/dedicated/akamai/architecture.mdx +9 -9
  27. package/docs/dev-portal/zudoku/components/browser-window.mdx +94 -0
  28. package/docs/dev-portal/zudoku/components/landing-page.mdx +283 -0
  29. package/docs/handlers/system-handlers.mdx +2 -1
  30. package/docs/mcp-gateway/how-to/connect-upstream-api-key.mdx +2 -2
  31. package/docs/mcp-gateway/observability/analytics.mdx +17 -13
  32. package/docs/mcp-gateway/quickstart.mdx +4 -3
  33. package/docs/mcp-gateway/troubleshooting.mdx +4 -4
  34. package/docs/policies/_index.md +1 -0
  35. package/docs/policies/data-loss-prevention-inbound/doc.md +23 -24
  36. package/docs/policies/data-loss-prevention-inbound/intro.md +9 -9
  37. package/docs/policies/data-loss-prevention-outbound/doc.md +25 -26
  38. package/docs/policies/data-loss-prevention-outbound/intro.md +10 -10
  39. package/docs/policies/graphql-analytics-outbound/doc.md +93 -0
  40. package/docs/policies/graphql-analytics-outbound/intro.md +12 -0
  41. package/docs/policies/graphql-analytics-outbound/schema.json +93 -0
  42. package/docs/programmable-api/zuplo-context.mdx +3 -2
  43. package/package.json +4 -4
@@ -8,29 +8,27 @@ tags:
8
8
  - backends
9
9
  ---
10
10
 
11
- Zuplo fronts GraphQL APIs the same way it fronts REST: requests pass through a
12
- gateway route with whatever authentication, rate limiting, and
13
- GraphQL-specific policies you attach and your Dev Portal documents the schema.
14
- This guide covers both halves: adding a GraphQL endpoint to your gateway routes,
15
- then rendering a schema reference and playground in the Dev Portal with
16
- `@zudoku/plugin-graphql`.
17
-
18
- ## Prerequisites
19
-
20
- - A Zuplo project
21
- - An upstream GraphQL API to proxy
22
- - For the Dev Portal section: your project's
23
- [Dev Portal](../dev-portal/introduction.mdx) lives in its `docs/` folder. The
24
- plugin requires the `zudoku` package version `0.80.1` or newer — check the
25
- version in `docs/package.json` and
26
- [update the Dev Portal](../dev-portal/updating.mdx) if yours is older.
11
+ Zuplo fronts a GraphQL API like any other backend: requests pass through a
12
+ gateway route with the policies you attach, and your Dev Portal documents the
13
+ schema. This guide proxies the endpoint, reports failed operations to analytics,
14
+ and publishes a schema reference and playground.
15
+
16
+ :::tip{title="TL;DR"}
17
+
18
+ - [ ] Proxy your GraphQL endpoint through a route with the URL Rewrite handler
19
+ - [ ] Tag the route with the `x-graphql` extension so the Portal recognizes it
20
+ - [ ] Surface failed operations with the `graphql-analytics-outbound` policy
21
+ - [ ] Publish a schema reference and playground with the `graphqlPlugin` for the
22
+ Developer Portal
23
+
24
+ :::
27
25
 
28
26
  ## Add a GraphQL endpoint to your gateway
29
27
 
30
- A GraphQL API serves every query and mutation from a single endpoint, so the
31
- gateway route uses the [URL Rewrite handler](../handlers/url-rewrite.mdx) —
32
- every request goes to exactly the upstream URL — rather than URL Forward, which
33
- appends the incoming path.
28
+ Because GraphQL uses a single endpoint, the route uses the
29
+ [URL Rewrite handler](../handlers/url-rewrite.mdx) — every request goes to
30
+ exactly the upstream URL — rather than URL Forward, which appends the incoming
31
+ path.
34
32
 
35
33
  ### Add a new GraphQL route
36
34
 
@@ -45,10 +43,11 @@ appends the incoming path.
45
43
  2. **Add the endpoint**
46
44
 
47
45
  Click **Add** and select **GraphQL Endpoint**. This creates a `POST /graphql`
48
- route preconfigured with the URL Rewrite handler and a demo upstream. If
49
- `/graphql` is already taken, the Portal appends a short suffix (for example
50
- `/graphql-b891`) edit the path to whatever you prefer. GraphQL routes show
51
- a **GraphQL** badge in the route list instead of an HTTP method.
46
+ route preconfigured with the URL Rewrite handler, a demo upstream, and the
47
+ [GraphQL Analytics policy](#report-failed-operations-to-analytics) for error
48
+ reporting. If `/graphql` is already taken, the Portal appends a short suffix
49
+ (for example `/graphql-b891`) edit the path to whatever you prefer. GraphQL
50
+ routes show a **GraphQL** badge in the route list instead of an HTTP method.
52
51
 
53
52
  3. **Point it at your upstream**
54
53
 
@@ -106,65 +105,103 @@ set:
106
105
 
107
106
  :::tip{title="Secure the endpoint"}
108
107
 
109
- GraphQL has its own attack surface deeply nested queries, expensive
110
- operations, and schema introspection. Zuplo ships policies for all three. See
108
+ Zuplo ships policies for query depth, complexity, and introspection. See
111
109
  [Secure your GraphQL API](./graphql-security.mdx) to add complexity limits and
112
110
  disable introspection in production.
113
111
 
114
112
  :::
115
113
 
116
- ## Document the API in your Dev Portal
114
+ ## Report failed operations to analytics
115
+
116
+ Failed GraphQL operations return `200 OK` with an `errors[]` array in the body
117
+ (the Apollo Server and graphql-yoga convention). HTTP-level analytics read that
118
+ `200` as a success, so those failures never show up on the
119
+ [GraphQL analytics dashboard](../analytics/tabs/graphql.md).
117
120
 
118
- The `@zudoku/plugin-graphql` package renders GraphQL APIs in your Dev Portal
119
- from a schema. Each plugin instance produces a browsable type reference
120
- (queries, mutations, objects, enums, and so on) plus a playground, generated
121
- straight from your schema.
121
+ The **GraphQL Analytics** policy closes that gap. It reads each response body,
122
+ counts the GraphQL errors, and classifies every one by its `extensions.code` —
123
+ `syntax`, `validation`, `auth`, `timeout`, or `resolver` so failed operations
124
+ appear on the dashboard as failures, broken down by error class. The response
125
+ passes through to the client unchanged.
122
126
 
123
127
  :::caution{title="Beta"}
124
128
 
125
- The GraphQL plugin is in beta. During the beta it isn't available in your
126
- project's working copy it only works in projects
127
- [connected to source control](./source-control.mdx).
129
+ The GraphQL Analytics policy is in beta. You can use it today, but it may change
130
+ in non-backward compatible ways before the final release.
128
131
 
129
132
  :::
130
133
 
131
- <Stepper>
134
+ New GraphQL endpoints include this policy automatically — the
135
+ [Add a new GraphQL route](#add-a-new-graphql-route) flow attaches a
136
+ `graphql-analytics-outbound` policy to the route's `outbound` chain, so error
137
+ reporting works out of the box. If you instead
138
+ [marked an existing route as GraphQL](#mark-an-existing-route-as-graphql), add a
139
+ `graphql-analytics-outbound` policy and reference it in that route's `outbound`
140
+ list.
132
141
 
133
- 1. **Install the plugin**
142
+ Tune the policy by editing its `options` in `config/policies.json`. Out of the
143
+ box it classifies the standard Apollo error codes — for example, it reports
144
+ `GRAPHQL_VALIDATION_FAILED` as `validation` and `UNAUTHENTICATED` as `auth` —
145
+ and falls back to `resolver` for anything it doesn't recognize:
134
146
 
135
- In your project's `docs/` folder (where `zudoku.config.tsx` lives), install
136
- the plugin:
147
+ ```json title="config/policies.json"
148
+ {
149
+ "policies": [
150
+ {
151
+ "name": "graphql-analytics",
152
+ "policyType": "graphql-analytics-outbound",
153
+ "handler": {
154
+ "export": "GraphqlAnalyticsOutboundPolicy",
155
+ "module": "$import(@zuplo/runtime)",
156
+ "options": {
157
+ "errorCodeClassification": {
158
+ "RATE_LIMITED": "resolver",
159
+ "NOT_LOGGED_IN": "auth"
160
+ },
161
+ "defaultErrorClass": "resolver",
162
+ "logErrors": true
163
+ }
164
+ }
165
+ }
166
+ ]
167
+ }
168
+ ```
137
169
 
138
- ```bash
139
- npm install @zudoku/plugin-graphql
140
- ```
170
+ - `errorCodeClassification` — Maps custom `extensions.code` values your server
171
+ emits to an error class. Entries merge over, and win against, the built-in
172
+ Apollo code map. Defaults to none.
173
+ - `defaultErrorClass` — The class for an error whose code is missing or
174
+ unrecognized. One of `syntax`, `validation`, `auth`, `timeout`, or `resolver`.
175
+ Defaults to `resolver`.
176
+ - `logErrors` — When `true`, also writes a structured warning to the request log
177
+ — the message, code, and path of each error, capped at the first 10 — for
178
+ every errored response. Defaults to `false`.
179
+ - `maxResponseBytes` — The largest response body, in bytes, the policy inspects.
180
+ Larger responses pass through unscanned, so any errors they carry go
181
+ unreported. Defaults to `5242880` (5 MiB).
182
+
183
+ See the
184
+ [GraphQL Analytics policy reference](../policies/graphql-analytics-outbound.mdx)
185
+ for the full classification table and schema.
141
186
 
142
- The plugin requires `zudoku` `0.80.1` or newer.
187
+ ## Document the API in your Dev Portal
143
188
 
144
- 2. **Add a schema**
189
+ The `@zudoku/plugin-graphql` package renders a browsable type reference and a
190
+ playground in your Dev Portal, generated from your schema. Register one instance
191
+ per API.
145
192
 
146
- Drop a GraphQL schema definition language (SDL) file next to your config:
193
+ :::caution{title="Beta"}
147
194
 
148
- ```graphql title="schema.graphql"
149
- type Query {
150
- product(id: ID!): Product
151
- }
195
+ The GraphQL plugin is in beta.
152
196
 
153
- type Product {
154
- id: ID!
155
- name: String!
156
- price: Float!
157
- }
158
- ```
197
+ :::
159
198
 
160
- Don't have an SDL file handy? Skip this step and introspect a live endpoint
161
- at build time with `type: "url"` in the next step — the schema is fetched for
162
- you when the portal builds.
199
+ <Stepper>
163
200
 
164
- 3. **Register the plugin**
201
+ 1. **Register the plugin**
165
202
 
166
203
  Import `graphqlPlugin` and add an instance per API. The `path` is where the
167
- docs mount, and `input` points at your schema:
204
+ docs mount, and `input` points at your GraphQL endpoint:
168
205
 
169
206
  ```tsx title="zudoku.config.tsx"
170
207
  import { graphqlPlugin } from "@zudoku/plugin-graphql";
@@ -172,15 +209,12 @@ project's working copy — it only works in projects
172
209
  const config = {
173
210
  plugins: [
174
211
  graphqlPlugin({
175
- type: "file",
176
- input: "./schema.graphql",
212
+ type: "url",
213
+ input: "https://graphql.example.com/api",
177
214
  path: "/graphql/ecommerce",
178
215
  options: {
179
216
  title: "E-Commerce GraphQL API",
180
217
  description: "Products, orders, and customers.",
181
- playground: {
182
- endpoint: "https://my-gateway.example.com/graphql",
183
- },
184
218
  },
185
219
  }),
186
220
  ],
@@ -189,18 +223,33 @@ project's working copy — it only works in projects
189
223
  export default config;
190
224
  ```
191
225
 
192
- Set `playground.endpoint` to the gateway route from the first half of this
193
- guide so readers run real queries through your gateway. With a file-based
194
- schema the plugin doesn't know where your API lives leave the endpoint
195
- unset and the reference pages still render, but the playground asks you to
196
- configure `options.playground.endpoint` before it can run operations.
226
+ With `type: "url"`, the portal fetches the schema via introspection at build
227
+ time, and the playground sends operations to that same URL by default. Point
228
+ `input` at the gateway route from the first half of this guide so readers run
229
+ real queries through your gateway or keep the playground separate from the
230
+ schema source with `options.playground.endpoint`.
231
+
232
+ Have a GraphQL schema definition language (SDL) file instead of a live
233
+ endpoint? Use `type: "file"` and set `input` to the file's path (for example
234
+ `./schema.graphql`). A file-based schema doesn't tell the plugin where your
235
+ API lives, so also set `options.playground.endpoint` — without it the
236
+ reference pages still render, but the playground asks for an endpoint before
237
+ it can run operations.
238
+
239
+ You can register the plugin more than once to document several schemas, each
240
+ with its own `path`.
241
+
242
+ :::note
243
+
244
+ New projects ship with `@zudoku/plugin-graphql` in `dependencies` already.
245
+ Older projects might need to add it to `docs/package.json`. The plugin
246
+ requires `zudoku` version `0.80.1` or newer.
247
+ [Update the Dev Portal](../dev-portal/updating.mdx) to get the latest
248
+ version.
197
249
 
198
- With `type: "url"`, set `input` to your GraphQL endpoint's URL instead: the
199
- schema is fetched via introspection when the portal builds, and the
200
- playground defaults to that same URL. You can register the plugin more than
201
- once to document several schemas, each with its own `path`.
250
+ :::
202
251
 
203
- 4. **Link it in the navigation**
252
+ 2. **Link it in the navigation**
204
253
 
205
254
  Point a navigation link at the instance's `path`. Set `stack: true` so the
206
255
  API's own pages render as a stacked sub-navigation instead of expanding
@@ -270,6 +319,8 @@ playground runs operations against your configured endpoint.
270
319
  introspection policies
271
320
  - [Testing GraphQL queries](./testing-graphql.mdx) — test the endpoint from the
272
321
  Zuplo Portal or external tools
322
+ - [GraphQL analytics](../analytics/tabs/graphql.md) — monitor operation volume,
323
+ latency, and error classes once traffic flows
273
324
  - [URL Rewrite handler](../handlers/url-rewrite.mdx) — full reference for the
274
325
  handler GraphQL routes use
275
326
  - [MCP Server GraphQL endpoints](../mcp-server/graphql.mdx) — expose GraphQL
@@ -39,7 +39,8 @@ If you're not familiar with Zuplo, it's recommended to go through
39
39
 
40
40
  1. Create an **MCP Server**
41
41
 
42
- On your `routes.oas.json` file, choose **Add** and then **MCP Server**.
42
+ On your `routes.oas.json` file, choose **Add** and then **Dynamic OpenAPI to
43
+ MCP Server**.
43
44
 
44
45
  ![Add Route](../../public/media/mcp-quickstart/add-mcp-route.png)
45
46
 
@@ -21,8 +21,12 @@ If you're not familiar with Zuplo, it's recommended to go through the
21
21
  Let's import an OpenAPI document. You can download this one here
22
22
  [todo-openapi.json](https://download-open-api-main-fae215f.d2.zuplo.dev/todo-openapi).
23
23
 
24
+ <ModalScreenshot size="sm">
25
+
24
26
  ![Import OpenAPI](../../public/media/mcp-quickstart/import-openapi.png)
25
27
 
28
+ </ModalScreenshot>
29
+
26
30
  Select the **Code** tab (1), then choose the `routes.oas.json` file (2) and
27
31
  choose **Import OpenAPI** (3).
28
32
 
@@ -49,7 +53,8 @@ If you're not familiar with Zuplo, it's recommended to go through the
49
53
 
50
54
  1. Create an **MCP Server**
51
55
 
52
- On your `routes.oas.json` file, choose **Add** and then **MCP Server** (3)
56
+ On your `routes.oas.json` file, choose **Add** and then **Dynamic OpenAPI to
57
+ MCP Server** (3)
53
58
 
54
59
  ![Add Route](../../public/media/mcp-quickstart/add-mcp-route.png)
55
60
 
@@ -10,8 +10,8 @@ tags:
10
10
 
11
11
  Sometimes multiple types of authentication are needed on an API. For example, an
12
12
  API could support JWT Authentication and API Key authentication or two different
13
- OAuth providers (for example Azure AD for employees and Auth0 for partners).
14
- Configuring multiple policies in Zuplo can be done in several ways.
13
+ OAuth providers (for example Microsoft Entra ID for employees and Auth0 for
14
+ partners). Configuring multiple policies in Zuplo can be done in several ways.
15
15
 
16
16
  ## JWT and API Key Authentication
17
17
 
@@ -15,7 +15,8 @@ this is an OpenAPI document used for routing.
15
15
  You can use the Route Designer to build your routes, which will be creating an
16
16
  OpenAPI document in the background for you (check it out in the **JSON View**).
17
17
 
18
- You can also **import an OpenAPI** document by clicking the **Open API** tab.
18
+ You can also **import an OpenAPI** document by clicking the **Import** button in
19
+ the Route Designer.
19
20
 
20
21
  ![Import Open API](../../public/media/open-api/image-1.png)
21
22
 
@@ -39,8 +40,12 @@ document and will keep your Zuplo settings intact, while overwriting everything
39
40
  else from your imported OpenAPI docs. This creates a great workflow, whatever
40
41
  toolset you use.
41
42
 
43
+ <ModalScreenshot>
44
+
42
45
  ![Import OpenAPI dialog](../../public/media/open-api/28512107-8c41-4974-8319-c9ec50734331.png)
43
46
 
47
+ </ModalScreenshot>
48
+
44
49
  What's more, you can now have more confidence that your OpenAPI represents the
45
50
  truth of your API implementation - because it now drives the configuration of
46
51
  your gateway.
@@ -23,8 +23,12 @@ disconnect the project from Source Control.
23
23
  Next create a new project in the correct account if moving accounts or with the
24
24
  correct name. Choose the `Advanced` option on the new project dialog.
25
25
 
26
+ <ModalScreenshot>
27
+
26
28
  ![Import existing project](../../public/media/source-control/image-1.png)
27
29
 
30
+ </ModalScreenshot>
31
+
28
32
  You should see a list of organizations and repositories - pick the source
29
33
  repository you wanted to move and click **Create Project from repository**.
30
34
 
@@ -29,8 +29,12 @@ Open the **Settings** section of your project and select **Environment
29
29
  Variables**. Create a new variable and name it `BACKEND_SECRET`. Set the value
30
30
  to a secure, random value. Ensure that the value is marked as a secret.
31
31
 
32
+ <ModalScreenshot>
33
+
32
34
  ![Set Environment Variable](../../public/media/securing-backend-shared-secret/image.png)
33
35
 
36
+ </ModalScreenshot>
37
+
34
38
  ### Step 2: Create a set header policy
35
39
 
36
40
  Create a policy that sets the `BACKEND_SECRET` as a header on the request to
@@ -40,8 +44,12 @@ is sent to your backend.
40
44
  Navigate to the route you want to secure and add a new policy. Select the **Add
41
45
  or Set Request Headers** policy type and configure it as follows:
42
46
 
47
+ <ModalScreenshot>
48
+
43
49
  ![Set Header Policy](../../public/media/securing-backend-shared-secret/image-1.png)
44
50
 
51
+ </ModalScreenshot>
52
+
45
53
  The configuration uses the environment variable via the `$env(BACKEND_SECRET)`
46
54
  selector as shown below.
47
55
 
@@ -98,10 +106,10 @@ interested in using this option please contact us at `support@zuplo.com`.
98
106
  Utilize the IAM controls provided by your Cloud host to secure inbound requests
99
107
  and allow only authorized service principals access to your service.
100
108
 
101
- - For Azure users, you can user our
109
+ - For Azure users, you can use the
102
110
  [Upstream Azure AD Service Auth](../policies/upstream-azure-ad-service-auth-inbound.mdx)
103
- policy. This uses Azure AD App registrations to create a token that Zuplo will
104
- send to requests to Azure.
111
+ policy. This uses Microsoft Entra ID (formerly Azure AD) App registrations to
112
+ create a token that Zuplo sends with requests to Azure.
105
113
 
106
114
  - For GCP users, you can use our
107
115
  [Upstream GCP Service AUth](../policies/upstream-gcp-service-auth-inbound.mdx)
@@ -130,8 +130,12 @@ If you have an existing GitHub repository that contains a Zuplo project, you can
130
130
  connect to that repository when you create a new project. Select **Import
131
131
  existing project** then select your GitHub organization and repository.
132
132
 
133
+ <ModalScreenshot>
134
+
133
135
  ![Import existing project to Zuplo](../../public/media/source-control/image-1.png)
134
136
 
137
+ </ModalScreenshot>
138
+
135
139
  ## What's Included
136
140
 
137
141
  With GitHub connected, you get:
@@ -226,8 +226,8 @@ period of inactivity is slow. Subsequent requests are fast.
226
226
 
227
227
  ### Analytics Dashboard
228
228
 
229
- Zuplo's analytics dashboard provides at-a-glance visibility into your API's
230
- performance. Use it to:
229
+ Zuplo's analytics dashboard, in the **Observability** tab of your project,
230
+ provides at-a-glance visibility into your API's performance. Use it to:
231
231
 
232
232
  - Identify slow endpoints by reviewing request latency data
233
233
  - Filter by route, API key, or time period to isolate patterns
@@ -177,9 +177,9 @@ const response = await fetch("https://api.example.com/data", {
177
177
  ### Portal live logs
178
178
 
179
179
  The Zuplo Portal provides real-time log viewing for deployed environments. Open
180
- the [**Environments**](https://portal.zuplo.com/+/account/project/environments)
181
- tab in your project, select the deployed environment, and open the logs tab to
182
- see live request logs and any messages logged with `context.log`.
180
+ the **Observability** tab in your project — the **Logs** view opens by default —
181
+ then use the **Environment** filter to select the deployed environment and see
182
+ live request logs and any messages logged with `context.log`.
183
183
 
184
184
  ### Using context.log
185
185
 
@@ -229,7 +229,7 @@ Zuplo and your backend services. For complete documentation, see
229
229
  | **Shared Secret / API Key** | Add a secret header to requests that only the gateway knows. Simple to implement and widely used by companies like Stripe and Supabase. |
230
230
  | **Zuplo JWT Service** | Issue signed JWTs that your backend validates using Zuplo's JWKS endpoint. Provides cryptographic proof that requests originate from your gateway. |
231
231
  | **mTLS (Mutual TLS)** | Certificate-based authentication where both gateway and backend present certificates. Provides zero-trust security for enterprise requirements. |
232
- | **Cloud Provider IAM** | Use AWS IAM, GCP Identity-Aware Proxy, or Azure AD to authorize requests. No credentials to manage - uses federated identity. |
232
+ | **Cloud Provider IAM** | Use AWS IAM, GCP Identity-Aware Proxy, or Microsoft Entra ID to authorize requests. No credentials to manage - uses federated identity. |
233
233
  | **Secure Tunnel (VPN)** | WireGuard-based tunnel for backends that can't be exposed to the internet. Useful for on-premise or bare-metal deployments. |
234
234
  | **Private Network** | VPC peering, PrivateLink, or Transit Gateway for private connectivity without traversing the public internet. |
235
235
 
@@ -238,14 +238,14 @@ Zuplo and your backend services. For complete documentation, see
238
238
  While most authentication methods work anywhere, some approaches are better
239
239
  suited for specific scenarios:
240
240
 
241
- | Backend Location | Recommended Methods | Notes |
242
- | ---------------------------- | ------------------------------------------------- | --------------------------------------------------------------------------- |
243
- | **Akamai Connected Cloud** | Shared secret, Zuplo JWT, mTLS | All methods work well; choose based on your security requirements |
244
- | **AWS** | AWS IAM (federated identity), mTLS, shared secret | IAM provides credential-free auth; works with Lambda, API Gateway, ECS, EKS |
245
- | **GCP** | GCP Identity-Aware Proxy, GCP Service Auth, mTLS | IAP provides zero-trust access to Cloud Run, GKE, and Compute Engine |
246
- | **Azure** | Azure AD Service Auth, mTLS, shared secret | Azure AD integrates with App Service, Functions, and AKS |
247
- | **On-Premise / Data Center** | Secure tunnel, mTLS, shared secret | Tunnel allows private connectivity; mTLS provides strong authentication |
248
- | **Third-Party APIs** | Shared secret, API keys, mTLS | Use whatever the third-party API supports |
241
+ | Backend Location | Recommended Methods | Notes |
242
+ | ---------------------------- | ---------------------------------------------------- | --------------------------------------------------------------------------- |
243
+ | **Akamai Connected Cloud** | Shared secret, Zuplo JWT, mTLS | All methods work well; choose based on your security requirements |
244
+ | **AWS** | AWS IAM (federated identity), mTLS, shared secret | IAM provides credential-free auth; works with Lambda, API Gateway, ECS, EKS |
245
+ | **GCP** | GCP Identity-Aware Proxy, GCP Service Auth, mTLS | IAP provides zero-trust access to Cloud Run, GKE, and Compute Engine |
246
+ | **Azure** | Microsoft Entra ID Service Auth, mTLS, shared secret | Microsoft Entra ID integrates with App Service, Functions, and AKS |
247
+ | **On-Premise / Data Center** | Secure tunnel, mTLS, shared secret | Tunnel allows private connectivity; mTLS provides strong authentication |
248
+ | **Third-Party APIs** | Shared secret, API keys, mTLS | Use whatever the third-party API supports |
249
249
 
250
250
  ### Choosing an authentication method
251
251
 
@@ -0,0 +1,94 @@
1
+ ---
2
+ title: Browser Window
3
+ sidebar_icon: app-window
4
+ ---
5
+
6
+ import { BrowserWindow } from "zudoku/components";
7
+ import { Button } from "zudoku/ui/Button";
8
+
9
+ A mock browser window for presenting UI previews, screenshots-as-code, or full page layouts in your
10
+ documentation. It renders its children inside a browser-style frame with a URL bar and an optional
11
+ zoom control — the current scale is displayed like in a real browser and readers can zoom in and out
12
+ themselves.
13
+
14
+ ## Import
15
+
16
+ ```tsx
17
+ import { BrowserWindow } from "zudoku/components";
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ <BrowserWindow>
23
+ <div className="flex flex-col items-center gap-3 p-10 text-center">
24
+ <span className="text-2xl font-bold">Hello, world!</span>
25
+ <p className="text-muted-foreground">Any content renders inside the browser frame.</p>
26
+ <Button>Get started</Button>
27
+ </div>
28
+ </BrowserWindow>
29
+
30
+ ```tsx
31
+ <BrowserWindow>
32
+ <div className="flex flex-col items-center gap-3 p-10 text-center">
33
+ <span className="text-2xl font-bold">Hello, world!</span>
34
+ <p className="text-muted-foreground">Any content renders inside the browser frame.</p>
35
+ <Button>Get started</Button>
36
+ </div>
37
+ </BrowserWindow>
38
+ ```
39
+
40
+ ## Scale
41
+
42
+ Use the `scale` prop to set the initial zoom of the content. This is useful for presenting
43
+ full-width layouts, like a landing page, at a reduced size. Passing a `scale` enables the zoom
44
+ control in the toolbar showing the current scale — readers can change it with the `+`/`-` buttons or
45
+ click the percentage to reset it, just like in a real browser. Without a `scale`, the zoom control
46
+ is hidden and the content renders at full size (pass `scale={1}` to start at 100% with the control
47
+ enabled).
48
+
49
+ <BrowserWindow scale={0.5}>
50
+ <div className="flex flex-col items-center gap-3 p-10 text-center">
51
+ <span className="text-4xl font-bold">Scaled to 50%</span>
52
+ <p className="text-muted-foreground">
53
+ The content is laid out at full width and scaled down to fit.
54
+ </p>
55
+ </div>
56
+ </BrowserWindow>
57
+
58
+ ```tsx
59
+ <BrowserWindow scale={0.5}>
60
+ <div className="flex flex-col items-center gap-3 p-10 text-center">
61
+ <span className="text-4xl font-bold">Scaled to 50%</span>
62
+ <p className="text-muted-foreground">
63
+ The content is laid out at full width and scaled down to fit.
64
+ </p>
65
+ </div>
66
+ </BrowserWindow>
67
+ ```
68
+
69
+ Scaling affects layout, not just size: at `scale={0.5}` the content is laid out at twice the
70
+ container width and scaled down, so responsive layouts behave as if viewed on a larger screen.
71
+
72
+ ## URL
73
+
74
+ Set the `url` prop to change the address shown in the URL bar (defaults to `localhost:3000`):
75
+
76
+ <BrowserWindow url="https://developers.example.com">
77
+ <p className="p-10 text-center text-muted-foreground">Your developer portal</p>
78
+ </BrowserWindow>
79
+
80
+ ```tsx
81
+ <BrowserWindow url="https://developers.example.com">
82
+ <p className="p-10 text-center text-muted-foreground">Your developer portal</p>
83
+ </BrowserWindow>
84
+ ```
85
+
86
+ ## Props
87
+
88
+ | Prop | Type | Description |
89
+ | ------------------ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
90
+ | `url` | `string` | Address displayed in the URL bar. Defaults to `localhost:3000`. |
91
+ | `scale` | `number` | Initial zoom of the content (e.g. `0.75` for 75%). Enables the zoom control; if omitted, the control is hidden and content renders at full size. |
92
+ | `className` | `string` | Additional classes for the outer frame. |
93
+ | `contentClassName` | `string` | Additional classes for the content viewport. |
94
+ | `children` | `ReactNode` | The content rendered inside the browser window. |