docs: specify SDK environment variables and compatibility (#126)

* docs: initial sdk compatability docs

* feat: style and update docs

* fit: ignore logo for redirects
This commit is contained in:
abelanger5
2024-02-03 20:16:03 -08:00
committed by GitHub
parent 0aa7b782a1
commit d97fe63149
37 changed files with 1426 additions and 97 deletions
+12 -1
View File
@@ -3,4 +3,15 @@ const withNextra = require('nextra')({
themeConfig: './theme.config.tsx',
})
module.exports = withNextra()
module.exports = {
...withNextra(),
async redirects() {
return [
{
source: '/:path((?!home|contributing|favicon\\.ico|hatchet_logo\\.png).*)',
destination: '/home/:path*',
permanent: true,
},
];
},
}
+4 -1
View File
@@ -19,11 +19,14 @@
},
"homepage": "https://github.com/shuding/nextra-docs-template#readme",
"dependencies": {
"autoprefixer": "^10.4.17",
"next": "^13.0.6",
"nextra": "^2.13.2",
"nextra-theme-docs": "^2.13.2",
"postcss": "^8.4.33",
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"tailwindcss": "^3.4.1"
},
"devDependencies": {
"@types/node": "18.11.10",
+17
View File
@@ -0,0 +1,17 @@
import type { AppProps } from "next/app";
// import { Inter } from "@next/font/google";
import "../styles/global.css";
// const inter = Inter({ subsets: ["latin"] });
function MyApp({ Component, pageProps }: AppProps) {
return (
<>
<main className="bg-[#020817]">
<Component {...pageProps} />
</main>
</>
);
}
export default MyApp;
+13 -6
View File
@@ -1,7 +1,14 @@
{
"index": "Introduction",
"quickstart": "Quickstart",
"python-sdk": "Python SDK",
"typescript-sdk": "TypeScript SDK",
"go-sdk": "Go SDK"
}
"home": {
"title": "Home",
"type": "page"
},
"self-hosting": {
"title": "Self Hosting",
"type": "page"
},
"contributing": {
"title": "Contributing",
"type": "page"
}
}
@@ -0,0 +1,4 @@
{
"index": "Contributing",
"sdks": "SDKs"
}
+147
View File
@@ -0,0 +1,147 @@
# Contributing
> **Note:** this guide assumes you're using MacOS. We simply don't have the bandwidth to test local development on native Windows. Most distros of Linux should work and we would like to support them, so please file an issue if running into an issue with a common distro.
### Prerequisites
- `go 1.21+`
- `docker-compose`
- [`Taskfile`](https://taskfile.dev/installation/)
- The following additional devtools:
- `protoc`: `brew install protobuf@25`
- `caddy` and `nss`: `brew install caddy nss`
### Setup
1. Spin up Postgres and RabbitMQ: `docker-compose up -d`
2. Run `pnpm install` inside of `./frontend/app`.
3. Generate certificates needed for communicating between the Hatchet client and engine: `task generate-certs`
4. Generate keysets for encryption: `task generate-local-encryption-keys`
5. Create environment variables:
```sh
alias randstring='f() { openssl rand -base64 69 | tr -d "\n" | tr -d "=+/" | cut -c1-$1 };f'
cat > .env <<EOF
DATABASE_URL='postgresql://hatchet:hatchet@127.0.0.1:5431/hatchet'
SERVER_TLS_CERT_FILE=./hack/dev/certs/cluster.pem
SERVER_TLS_KEY_FILE=./hack/dev/certs/cluster.key
SERVER_TLS_ROOT_CA_FILE=./hack/dev/certs/ca.cert
SERVER_ENCRYPTION_MASTER_KEYSET_FILE=./hack/dev/encryption-keys/master.key
SERVER_ENCRYPTION_JWT_PRIVATE_KEYSET_FILE=./hack/dev/encryption-keys/private_ec256.key
SERVER_ENCRYPTION_JWT_PUBLIC_KEYSET_FILE=./hack/dev/encryption-keys/public_ec256.key
SERVER_PORT=8080
SERVER_URL=https://app.dev.hatchet-tools.com
SERVER_AUTH_COOKIE_SECRETS="$(randstring 16) $(randstring 16)"
SERVER_AUTH_COOKIE_DOMAIN=app.dev.hatchet-tools.com
SERVER_AUTH_COOKIE_INSECURE=false
SERVER_AUTH_SET_EMAIL_VERIFIED=true
SERVER_LOGGER_LEVEL=debug
SERVER_LOGGER_FORMAT=console
DATABASE_LOGGER_LEVEL=debug
DATABASE_LOGGER_FORMAT=console
EOF
```
6. Migrate the database: `task prisma-migrate`
7. Generate all files: `task generate`
8. Seed the database: `task seed-dev`
9. Start the Hatchet engine, API server, dashboard, and Prisma studio:
```sh
task start-dev
```
### Creating and testing workflows
To create and test workflows, run the examples in the `./examples` directory.
You will need to add the tenant (output from the `task seed-dev` command) to the `.env` file in each example directory. An example `.env` file for the `./examples/simple` directory can be generated via:
```sh
alias get_token='go run ./cmd/hatchet-admin token create --name local --tenant-id 707d0855-80ab-4e1f-a156-f1c4546cbf52'
cat > ./examples/simple/.env <<EOF
HATCHET_CLIENT_TENANT_ID=707d0855-80ab-4e1f-a156-f1c4546cbf52
HATCHET_CLIENT_TLS_ROOT_CA_FILE=../../hack/dev/certs/ca.cert
HATCHET_CLIENT_TLS_SERVER_NAME=cluster
HATCHET_CLIENT_TOKEN="$(get_token)"
EOF
```
This example can then be run via `go run main.go` from the `./examples/simple` directory.
### Logging
You can set the following logging formats to configure your logging:
```
# info, debug, error, etc
SERVER_LOGGER_LEVEL=debug
# json or console
SERVER_LOGGER_FORMAT=json
DATABASE_LOGGER_LEVEL=debug
DATABASE_LOGGER_FORMAT=console
```
### OpenTelemetry
You can set the following to enable distributed tracing:
```
SERVER_OTEL_SERVICE_NAME=engine
SERVER_OTEL_COLLECTOR_URL=<collector-url>
# optional
OTEL_EXPORTER_OTLP_HEADERS=<optional-headers>
# optional
OTEL_EXPORTER_OTLP_ENDPOINT=<collector-url>
```
### CloudKMS
CloudKMS can be used to generate master encryption keys:
```
gcloud kms keyrings create "development" --location "global"
gcloud kms keys create "development" --location "global" --keyring "development" --purpose "encryption"
gcloud kms keys list --location "global" --keyring "development"
```
From the last step, copy the Key URI and set the following environment variable:
```
SERVER_ENCRYPTION_CLOUDKMS_KEY_URI=gcp-kms://projects/<PROJECT>/locations/global/keyRings/development/cryptoKeys/development
```
Generate a service account in GCP which can encrypt/decrypt on CloudKMS, then download a service account JSON file and set it via:
```
SERVER_ENCRYPTION_CLOUDKMS_CREDENTIALS_JSON='{...}'
```
## Issues
### Query engine leakage
Sometimes the spawned query engines from Prisma don't get killed when hot reloading. You can run `task kill-query-engines` on OSX to kill the query engines.
Make sure you call `.Disconnect` on the database config object when writing CLI commands which interact with the database. If you don't, and you try to wrap these CLI commands in a new command, it will never exit, for example:
```
export HATCHET_CLIENT_TOKEN="$(go run ./cmd/hatchet-admin token create --tenant-id <tenant>)"
```
+88
View File
@@ -0,0 +1,88 @@
# SDKs
This document tracks the feature support of the various SDKs, and aims to consolidate the expected behavior around environment variables and configuration loading.
## Environment Variables
Each SDK should support the following environment variables:
| Variable | Description | Required | Default |
| -------- | ----------- | -------- | ------- |
| `HATCHET_CLIENT_TOKEN` | The tenant-scoped API token to use. | Yes | N/A |
| `HATCHET_CLIENT_HOST_PORT` | The host and port of the Hatchet server to connect to, in `host:port` format. SDKs should handle schemes and trailing slashes, i.e. `https://host:port | Yes | N/A |
| `HATCHET_CLIENT_TLS_STRATEGY` | The TLS strategy to use. Valid values are `none`, `tls`, and `mtls`. | No | `tls` |
| `HATCHET_CLIENT_TLS_CERT_FILE` | The path to the TLS client certificate file to use. | Only if strategy is set to `mtls` | N/A |
| `HATCHET_CLIENT_TLS_CERT` | The TLS client key file to use. | Only if strategy is set to `mtls` | N/A |
| `HATCHET_CLIENT_TLS_KEY_FILE` | The path to the TLS client key file to use. | Only if strategy is set to `mtls` | N/A |
| `HATCHET_CLIENT_TLS_KEY` | The TLS client key to use. | Only if strategy is set to `mtls` | N/A |
| `HATCHET_CLIENT_TLS_ROOT_CA_FILE` | The path to the TLS root CA file to use. | Only if the server certificate is not signed by a public authority that's available to your environment | N/A |
| `HATCHET_CLIENT_TLS_ROOT_CA` | The TLS root CA to use. | Only if the server certificate is not signed by a public authority that's available to your environment | N/A |
| `HATCHET_CLIENT_TLS_SERVER_NAME` | The TLS server name to use. | No | Defaults to the `host` of the `host:port` |
The following environment variables are deprecated:
| Variable | Description | Explanation |
| -------- | ----------- | ----------- |
| `HATCHET_CLIENT_TENANT_ID` | The tenant ID to use. | This is now part of the token. |
## Compatibility Matrices
### DAGs
Whether the SDKs support full DAG-style execution.
| SDK | DAGs? | Notes |
| --- | ----- | ----- |
| Go SDK | Yes | |
| Python SDK | Yes | |
| Typescript SDK | Yes | |
### Timeouts
Whether the SDKs support setting timeouts and cancelling after timeouts.
| SDK | Timeouts? | Step cancellation? | Notes |
| --- | --------- | ------------------ | ----- |
| Go SDK | Yes | Yes | |
| Python SDK | Yes | Yes | If thread is blocking, this won't be respected |
| Typescript SDK | Yes | Unknown | |
### Middleware
Whether the SDKs support setting middleware.
| SDK | Middleware? | Notes |
| --- | ---------- | ----- |
| Go SDK | Yes | |
| Python SDK | No | |
| Typescript SDK | No | |
### Separately Registering and Calling Actions
Whether the SDKs support separately registering and calling actions, instead of defining them inline in the workflows.
| SDK | Supported? | Notes |
| --- | ----------------------------------------- | ----- |
| Go SDK | Yes | |
| Python SDK | No | |
| Typescript SDK | No | |
### Custom Services
Whether the SDKs support defining services to logically separate workflows and actions.
| SDK | Supported? | Notes |
| --- | --------- | ----- |
| Go SDK | Yes | |
| Python SDK | No | |
| Typescript SDK | No | |
### Scheduled Workflows
Whether the SDKs support defining scheduled workflows.
| SDK | Supported? | Notes |
| --- | --------- | ----- |
| Go SDK | Yes | |
| Python SDK | No | |
| Typescript SDK | No | |
+15
View File
@@ -0,0 +1,15 @@
{
"index": "Introduction",
"-- Getting Started": {
"type": "separator",
"title": "Getting Started"
},
"quickstart": "Quickstart",
"-- SDKs": {
"type": "separator",
"title": "SDKs"
},
"go-sdk": "Go SDK",
"python-sdk": "Python SDK",
"typescript-sdk": "TypeScript SDK"
}
+41
View File
@@ -0,0 +1,41 @@
# Introduction
Welcome to the Hatchet documentation! Hatchet is a self-hostable workflow engine which lets you define workflows as code.
## Concepts
**You run your workers, we manage the rest.**
Hatchet is an orchestrator, which means it manages the execution of your workflows. However, the individual steps of each workflow are executed by your own workers (don't worry, each SDK comes with a worker implementation). This means you can run your workers in your own infrastructure, and Hatchet will manage the scheduling, retries, and monitoring of your workflows.
**What is a workflow?**
The term `workflow` tends to be overloaded, so let's make things more clear - in Hatchet, a workflow is a set of functions which are executed in response to an external trigger (an event, schedule, or API call). For example, if you'd like to send notifications to a user after they've signed up, you could create a workflow for that.
**Why is that useful?**
Instead of processing background tasks and functions in your application handlers, which can lead to complex code, hard-to-debug errors, and resource contention, you can distribute these workflows between a set of `workers`. Workers are long-running processes which listen for events, and execute the functions defined in your workflows.
**What is a workflow engine?**
A workflow engine orchestrates the execution of workflows. It schedules workflows on workers, retries failed workflows, and provides integrations for monitoring and debugging workflows.
**Additional concepts**
We'll refer to a few additional terms throughout the documentation:
- `Workflow run` - an execution of a workflow. In Hatchet, the structure of the workflow is declared in your code, and each invocation of the workflow is a `run`.
- `Step` - a single function in a workflow. Steps can be executed in parallel, or in sequence, and can have timeouts and retries.
- `Event` - a type of trigger for a workflow. Events can be emitted by your application, or by an external system. For example, when a user signs up, you can send that as an event to Hatchet.
## Use-Cases
Hatchet is designed to support a broad set of use-cases, including:
- **Background tasks:** run tasks in the background, without blocking your application. This is particularly useful if you're running into timeouts on your API calls, or if you're running a long-running task which doesn't need to be synchronous.
- **Data pipelines:** process data from multiple sources, and transform it into a single output. For example, you could use Hatchet to process data from a database, an API, and a file, and then send the output to a third-party service.
- **Notifications:** send notifications to users based on events in your application. For example, you could send a welcome email to a user after they've signed up, or send a push notification when a user's order has been shipped.
- **Scheduled tasks:** run tasks on a schedule, without needing to manage cron jobs or other scheduling systems. For example, you could use Hatchet to send a weekly report to your users, or to clean up old data in your database.
- **Multi-step workflows:** run complex, multi-step workflows in response to events. For example, you could use Hatchet to process a user's order, including charging their credit card, updating the order status, and sending a confirmation email.
Check out the [Quickstart](/quickstart) guide to learn how to get started with Hatchet.
@@ -23,6 +23,8 @@ HATCHET_CLIENT_HOST_PORT=<hatchet-domain>:443
HATCHET_CLIENT_TOKEN="<your-api-key>"
```
## Advanced
### TLS with self-signed server certificates
> **Note:** All Hatchet instances use TLS by default. Instances on Hatchet Cloud use a publicly signed server certificate, and the server name is automatically set based on the domain.
+104
View File
@@ -0,0 +1,104 @@
import { Callout, Card, Cards, Steps, Tabs } from 'nextra/components'
# Quickstart
Welcome to Hatchet! This guide walks you through getting set up on Hatchet Cloud. If you'd like to self-host Hatchet, please see the [self-hosted quickstart](/self-hosting/quickstart) instead.
## Step 1 - Request Access
If you haven't already requested access to Hatchet Cloud, please fill out the form [here](https://hatchet.run/request-access). We'll get back to you within 1 business day.
## Step 2 - Set up your Development Tenant
Each Hatchet instance runs on a unique subdomain for your organization (e.g. `mycompany.onhatchet.run`). Within each instance, you can create multiple tenants to logically separate your environments (e.g. `dev`, `staging`, `production`). Each tenant has its own set of users who can access it.
When you get access to Hatchet, you'll be given a development tenant to use. This will allow you to create your development workflows and invite your team members to collaborate. We recommend utilizing a different development tenant for each engineer on your team.
When you get access to the tenant, navigate to your Hatchet dashboard and to your settings tab. You should see a section called "API Keys". Click "Create API Key", input a name for the key and copy the key. Then set the following environment variables:
```sh
HATCHET_CLIENT_HOST_PORT=<hatchet-domain>:443
HATCHET_CLIENT_TOKEN="<your-api-key>"
```
## Step 3 - Execute your first workflow
<Tabs items={['Python', 'Typescript']}>
<Tabs.Tab>
Make sure you have the following dependencies installed:
```sh
pip install python-dotenv
pip install hatchet-sdk
```
Then run the following code:
```python filename="worker.py" copy
from hatchet_sdk import Hatchet
from dotenv import load_dotenv
load_dotenv()
hatchet = Hatchet(debug=True)
@hatchet.workflow(name="first-python-workflow",on_events=["user:create"])
class MyWorkflow:
@hatchet.step()
def step1(self, context):
return {
"result": "success"
}
worker = hatchet.worker('first-worker')
worker.register_workflow(MyWorkflow())
worker.start()
```
</Tabs.Tab>
<Tabs.Tab>
Make sure you install `@hatchet-dev/typescript-sdk` via:
```sh npm2yarn
npm i @hatchet-dev/typescript-sdk
```
Then run the following code:
```typescript filename="worker.ts" copy
import Hatchet from '@hatchet-dev/typescript-sdk';
import { Workflow } from '@hatchet-dev/typescript-sdk/dist/workflow';
const hatchet = Hatchet.init();
const workflow: Workflow = {
id: 'first-typescript-workflow',
description: 'This is my first workflow',
on: {
event: 'user:create',
},
steps: [
{
name: 'step1',
run: async (ctx) => {
console.log('starting step1 with the following input', ctx.workflowInput());
return {
result: 'success!' };
},
},
],
};
hatchet.run(workflow);
```
</Tabs.Tab>
</Tabs>
After running your worker, you should see your first workflow registered in the Hatchet dashboard:
![Quickstart 1](/quickstart-1.png)
You can now trigger this workflow by clicking the top right "Trigger workflow" button when viewing the workflow:
![Quickstart 2](/quickstart-2.png)
@@ -0,0 +1,16 @@
# Setup
## Installation
```sh npm2yarn
npm i @hatchet-dev/typescript-sdk
```
## Usage
Navigate to your Hatchet dashboard and navigate to your settings tab. You should see a section called "API Keys". Click "Create API Key", input a name for the key and copy the key. Then set the following environment variables:
```sh
HATCHET_CLIENT_HOST_PORT=<hatchet-domain>:443
HATCHET_CLIENT_TOKEN="<your-api-key>"
```
-58
View File
@@ -1,58 +0,0 @@
# Introduction
Welcome to the Hatchet documentation! Hatchet is a self-hostable workflow engine built for application developers.
**What is a workflow?**
The term `workflow` tends to be overloaded, so let's make things more clear - in Hatchet, a workflow is a set of functions which are executed in response to an external trigger (an event, schedule, or API call). For example, if you'd like to send notifications to a user after they've signed up, you could create a workflow for that.
**Why is that useful?**
Instead of processing background tasks and functions in your application handlers, which can lead to complex code, hard-to-debug errors, and resource contention, you can distribute these workflows between a set of `workers`. Workers are long-running processes which listen for events, and execute the functions defined in your workflows.
**What is a workflow engine?**
A workflow engine orchestrates the execution of workflows. It schedules workflows on workers, retries failed workflows, and provides integrations for monitoring and debugging workflows.
## Project Goals
Hatchet has the following high-level goals:
1. **Serve application developers:** we aim to support a broad set of languages and frameworks, to make it easier to support your existing applications. We currently support a Go SDK, with more languages coming soon.
2. **Simple to setup:** we've seen too many overengineered stacks built on a fragile task queue with overly complex infrastructure. Hatchet is designed to be simple to setup, run locally, and deploy to your own infrastructure.
3. **Flexibility when you need it:** as your application grows, you can use Hatchet to support complex, multi-step distributed workflows. Hatchet's backend is modular, allowing for customizing the implementation of the event storage API, queueing system, authentication, and more.
## Features
We currently support the following features, with many more on the roadmap:
- **Declarative workflows:** define workflows which run when events occur, with support for timeouts, multi-step workflows, and parallel execution:
```go filename="worker.go" {3} copy
w.On(
worker.Event("event:test"),
&worker.WorkflowJob{
Name: "example-workflow",
Description: "Example workflow.",
Timeout: "60s",
Steps: []*worker.WorkflowStep{
{
Function: func(ctx context.Context, event *events.TestEvent) error {
fmt.Println("got event: ", event.Name)
return nil
},
},
},
},
)
```
- **Event storage API:** store events in a durable event log, with support for querying and filtering events:
![Workflow engine](/features-2.png)
- **Web platform for visibility and monitoring**: view the status of your workflows, and drill down into individual events:
![Workflow engine](/features-1.png)
Check out the [Quickstart](/quickstart) guide to work through a simple example of using Hatchet.
@@ -1,6 +1,6 @@
# Quickstart
> Note: this guide is written for Go developers. We have more SDKs on the roadmap, please [get in touch](mailto:contact@hatchet.run) if you would like to be notified when they're available (or you'd like to help us build one!).
> Note: this guide is written for Go developers. If you're not a Go developer, you can use the same repository to get the Hatchet instance set up, and use the other SDKs to interact with Hatchet.
## Prerequisites
@@ -1,30 +0,0 @@
# Setup
## Installation
If using `pnpm`, you can run:
```sh
pnpm add @hatchet/node-sdk
```
If using `npm`:
```sh
npm i @hatchet/node-sdk
```
If using `yarn`:
```sh
yarn add @hatchet/node-sdk
```
## Usage
Navigate to `https://app.dev.hatchet-tools.com/tenant-settings` to generate an API Token and set the following environment variables.
```sh
HATCHET_CLIENT_TOKEN=<your-token>
HATCHET_CLIENT_HOST_PORT=<hatchet-domain>:<hatchet-port>
```
+775
View File
File diff suppressed because it is too large Load Diff
+6
View File
@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 639 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 896 KiB

+163
View File
@@ -0,0 +1,163 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
--card: 222.2 84% 4.9%;
--card-foreground: 210 40% 98%;
--popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%;
--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 11.2%;
--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;
--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;
--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;
--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--ring: 212.7 26.8% 83.9%;
}
@layer base {
* {
@apply border;
}
}
body {
height: 100vh;
}
.step-run-card {
--transition: 0.25s;
--spark: 3s;
display: grid;
border-radius: 10px;
position: relative;
overflow: hidden;
box-shadow: 0 1000px 0 0 hsl(217.2 32.6% 17.5%) inset;
transition: box-shadow var(--transition), background var(--transition),
transform var(--transition);
}
.step-run-card.active .step-run-backdrop {
background: 222.2 84% 4.9%;
}
.step-run-card.active {
transform: scale(1.05);
}
.spark {
position: absolute;
inset: 0;
border-radius: 10px;
rotate: 0deg;
overflow: hidden;
mask: linear-gradient(white, transparent 50%);
animation: flip calc(var(--spark) * 2) infinite steps(2, end);
}
@keyframes flip {
to {
rotate: 360deg;
}
}
.spark:before {
content: "";
position: absolute;
width: 200%;
aspect-ratio: 1;
inset: 0 auto auto 50%;
z-index: -1;
translate: -50% -15%;
rotate: 0;
transform: rotate(-90deg);
opacity: 1;
background: conic-gradient(from 0deg, transparent 0 340deg, white 360deg);
transition: opacity var(--transition);
animation: rotate var(--spark) linear infinite both;
}
.step-run-backdrop {
position: absolute;
inset: 1px;
background: 222.2 84% 4.9%;
border-radius: 10px;
transition: background var(--transition) opacity var(--transition);
}
@keyframes rotate {
to {
transform: rotate(90deg);
}
}
.text {
z-index: 1;
color: rgb(203 213 225);
}
/* Code block styles */
.nextra-code-block pre {
background-color: #1e293b !important;
}
html.dark .nextra-code-block pre {
background-color: #1e293b !important;
}
/* Base dark mode styles */
html.dark body {
background-color: var(--background) !important;
}
html.dark div.nx-sticky.nx-bottom-0 {
background-color: var(--background) !important;
}
html.dark div.nextra-nav-container {
background-color: var(--background) !important;
}
.nextra-nav-container-blur {
background-color: var(--background) !important;
}
nav {
background-color: var(--background) !important;
}
.dark .nx-sticky {
box-shadow: none !important;
}
/* Center numbers in steps */
.nextra-steps h3::before {
line-height: 25px;
}
/* Breadcrumb link styles in dark mode */
.dark .nextra-breadcrumb a,
.dark .nextra-breadcrumb a:visited,
.dark .nextra-breadcrumb a:hover,
.dark .nextra-breadcrumb a:active {
background: none !important;
-webkit-text-fill-color: var(--ash-gray) !important;
}
:is(html[class~="dark"]) .nextra-nav-container-blur.nx-pointer-events-none {
background-color: var(--background) !important;
}
+15
View File
@@ -0,0 +1,15 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: 'class',
content: [
"./pages/**/*.{js,jsx,ts,tsx,md,mdx}",
"./components/**/*.{js,jsx,ts,tsx,md,mdx}",
// Or if using `src` directory:
"./src/**/*.{js,jsx,ts,tsx,md,mdx}",
],
theme: {
extend: {},
},
plugins: [],
};
+3
View File
@@ -24,6 +24,9 @@ const config: DocsThemeConfig = {
<title>Hatchet Documentation</title>{" "}
</>
),
sidebar: {
defaultMenuCollapseLevel: 1,
},
};
export default config;