pgx
PGX — Lightweight Postgres for AI agents. Written in Rust. Thousands of isolated databases in one runtime. 🐘
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗(The site is built with Docusaurus)
Stack: Docusaurus 3.10, React 19, Tailwind CSS 4, strict MDX 3.
Node. Use the version in .nvmrc (currently 24; package.json requires 22 or newer).
nvm use
Clone and install
git clone https://github.com/datazip-inc/olake-docs.git
cd olake-docs
npm install
Clear the cache after every git pull, after npm install, and after editing any plugin file in src/plugins (the compile cache does not notice plugin changes). A "Module not found" or ReactContextError on every page usually means a stale cache.
npm run clear
Start the development server
npm start
Your default browser opens the local site. Some effects are production-only (for example the generated image sizes), so check final results in a build.
Build (this is what CI runs; broken links and anchors only produce warnings in the build output)
CI=true npm run build
npm run build runs docusaurus build and then the image sitemap script. It does not touch the repo: the Open Graph images in static/img/og/ are generated by hand with npm run og-images and committed (see 1.2). To preview the output: npm run serve.
Optional checks (not run in CI)
| Command | What it checks |
|---|---|
npm run typecheck | tsc --noEmit over the TypeScript sources |
npm run lint:content | MDX and front matter rules for docs, blog, customer-stories, learn and compare files; details in 1.2. Errors fail the command only when you run it yourself. |
npm run og-images -- --check | Fails if a blog cover has no 1200x630 social card in static/img/og/, or the cover changed since the card was rendered. Writes nothing. Run it after adding a post or changing a cover. |
src/css/tokens.css holds the --olake-* colors, type scale and spacing for light and dark. Use the Tailwind olake-* utilities (defined in src/css/custom.css) or var(--olake-*); do not hard-code hex values in components.src/components/landing/ui/ (Button, Section, SectionHeading, Card, CtaBanner, LakesidePage). Build marketing pages from these.src/css/typography.css; do not set h1 size or weight in a component.@theme-original/<Component>) instead of copying it, so the swizzle survives Docusaurus upgrades.CI (test-deploy.yml on pull requests, deploy.yml on master) only builds the site; none of the checks below block a merge, and the legacy MDX syntax (<!-- --> comments, {#id} heading ids, :::note Title) still compiles. They are there so you can catch problems before opening a PR.
Run it locally
npm run lint:content # errors fail (exit 1), warnings are listed
npm run lint:content -- blog/2026-10-01-my-post.mdx # limit to a file or folder
npm run lint:content -- --strict # warnings fail too (optional, not used in CI)
npm run build # broken links and anchors are printed as warnings
Errors (fail lint:content when you run it). The preferred form for each:
| Rule | Correct form |
|---|---|
html-comment | {/* comment */}, never <!-- comment --> (only <!-- truncate --> is allowed) |
heading-id | ## Install {/* #install */}, never ## Install {#install} |
admonition-title | :::tip[Before you start], never :::tip Before you start |
second-h1 (posts) | The title comes from front matter; start body headings at ## and do not use # ... or <h1> |
old-blog-url | [Post](/blog/my-post-slug/), never /blog/2024/05/01/... |
title-length (posts) | title: at most 70 characters (put longer SEO wording in seo_title:) |
title-missing, title-entity (posts) | title: "Postgres to Iceberg", with no & or & |
description-missing | Every post and doc has a description: |
authors-missing, author-unknown | authors: [anshika], where the id exists in the folder's authors.yml |
tags-missing, tags-count, tag-undefined | tags: [olake, iceberg]: at least one, at most 8, each defined in the folder's tags.yml |
image-missing, image-path, image-not-found | image: /img/blog/cover/my-cover.webp starts with / and the file exists under static/ |
slug-space, slug-duplicate | Slugs are unique per folder and contain no spaces |
filename-space | No spaces in file names |
frontmatter-yaml | Front matter parses as YAML (quote values that contain :) |
Warnings (listed only; fix them in files you touch). A summary written as :::tip[TL;DR] or ## TL;DR instead of the component, a description outside 120-160 characters, <br> outside a table, bold lines used as headings, code fences without a language, heading level jumps, absolute https://olake.io/... links, a post that does not end with <BlogCTA/>, docs/shared partials that have front matter, and a file name date that differs from the date: field.
TLDR component. Write the post summary once, right after the opening paragraph, as a component with a blank line after the opening tag and before the closing tag:
<TLDR>
- Point one
- Point two
</TLDR>
Internal links. Link to /docs/, not /docs/intro/. lint:content does not check this. The build prints a warning for a link to a route that does not exist, so read the build output. A plain <section id="x"> is not collected as an anchor, so a <Link to="#x"> to it is reported as broken even though the id exists; use <a href="#x"> for in-page links on custom pages.
Common fixes
heading-id or html-comment on old content: rewrite the syntax by hand as shown above. Do not use npm run write-heading-ids, it writes the old {#id} form.title-length: shorten title: and move the full phrase to seo_title:. It feeds the page title, og:title and twitter:title, while the visible H1 stays short.tag-undefined or author-unknown: add the entry to that folder's tags.yml or authors.yml, or pick an existing one.image-not-found: check the case and extension of the file name under static/img/.Open Graph images. Every post cover needs a 1200x630 card in static/img/og/ (the post page points og:image and twitter:image at it). They are generated by hand and committed, not on every build:
npm run og-images # render only missing or stale cards, update scripts/og-images.manifest.json
npm run og-images -- --force # re-render every card
npm run og-images -- --check # write nothing, exit 1 if a card is missing or stale
A card is stale when the SHA-256 of its source cover no longer matches scripts/og-images.manifest.json. File times are not used. After adding a post or changing a cover, run npm run og-images and commit the new card and the manifest.
| Directory | When to use |
|---|---|
/blog | OLake and Iceberg topics, comparisons, alternatives and pricing |
/customer-stories | Case studies from teams that use OLake |
/learn | Plain-language explainers (served at /learn/<slug>/) |
/compare | New comparison, alternatives, pricing and best-of posts (served at /compare/<slug>/) |
Navigate to the correct directory.
Create an MDX file: YYYY-MM-DD-blog-slug.mdx.
The date reflects the publish date, not the commit date.
Copy the front-matter (metadata) from an existing post and update it.
Manage authors
blog/ and customer-stories/ have their own authors.yml. learn/ and compare/ have neither an authors.yml nor a tags.yml: they use blog/authors.yml and blog/tags.yml, so add a new author or tag there./learn/authors/ and /compare/authors/ list only the authors who have a post there. A compare/ post is filed under one of Alternatives, Versus, Pricing or Best-of by adding that tag (alternatives, versus, pricing, best-of, all in blog/tags.yml) to its front matter; the tag drives the filter row on /compare/ and is not shown in the post footer.Append <BlogCTA/> as the final line of every blog post.
static/img/blog/static/img/blog/cover/<slug>-cover.pngstatic/img/blog/YYYY/MM/<slug>-N.pngExample – slug flatten-array, published May 2025:
static/img/blog/cover/flatten-array-cover.webp
static/img/blog/2025/05/flatten-array-1.webp
static/img/blog/2025/05/flatten-array-2.webp
Create reusable React (.tsx) components in src/components.
Before creating, scan existing components for reuse.
To expose a component globally in MDX, import it once in
src/theme/MDXComponents/Index.js.
<MyComponent/> in any file under /blog or /docs.src/pages still require manual imports./docs.sidebars.js.
Order-of-appearance in the sidebar is defined here.docs/shared/.src/theme/MDXComponents/Index.js.<SharedComponent/> syntax.docs/shared/ is excluded from the docs build (exclude in docusaurus.config.js), so snippets are not published as pages or listed in the sitemap. They only render where they are imported. Do not link to /docs/shared/... URLs.| Topic | Details |
|---|---|
| Redirects | Configure in the @docusaurus/plugin-client-redirects list in docusaurus.config.js. Never leave a "moved" stub .mdx behind (see 6.5). |
CNAME | Do not delete static/CNAME; GitHub Pages needs it for olake.io. |
| Public files | Any asset in static is publicly accessible (e.g. /reddit.json). |
| Next.js | We may switch to the Next.js plug-in later for Lighthouse gains. |
| Embedding media | Images: Markdown ; use raw HTML for size control.Videos: embed via HTML. |
| MDX & HTML | MDX accepts all HTML except tables (use Markdown tables). |
| Docusaurus features | Components like <Tabs>, <TabItem>, :::info, etc. are native—see their docs. |
```py title="docker-compose.yml"
# code here
````
Supported lexers: py, bash, sh, js, jsx, go, yaml, yml, text, …
## Heading ✅
### Heading ✅
## **Heading** ❌
Use Docusaurus swizzle to override core components and UI of how . Swizzled files live in src/theme/.
We have already swizzled: blog pages, doc pages, navbar, and footer.
Add work-in-progress content to the root /drafts folder; it will not be published.
A draft that must live inside docs/, blog/ etc. needs draft: true in its frontmatter. A folder called docs/drafts/ is not hidden automatically: a page there is published and goes into the sitemap unless it has draft: true.
Breaking these has cost search traffic before. Run npm run build and npm run lint:content and look at the output before opening a PR.
trailingSlash: true; GitHub Pages 301s the no-slash URL to the slash URL, and the sitemap and hreflang use the slash URL. Never add your own <link rel="canonical"> and never strip the slash from a permalink. og:url and JSON-LD url/@id must match the canonical. Before the fix Google indexed both versions of 172 pages./slack/, /contact/, /blog/, also absolute https://olake.io/... links in MDX, which Docusaurus does not normalise). Use SLACK_URL instead of retyping the Slack link. A link without the slash costs a 301 hop on every click and crawl.slug, rename a doc or delete a page, add { from, to } to the client-redirects list in docusaurus.config.js in the same PR. In 2026-04 a top post changed slug without one and kept 404ing in search with about 500 clicks of history. Do not keep a "(Moved)" stub .mdx page. Put a slash before any # or ? in a redirect to; src/plugins/client-redirects-slash restores it in the generated stubs because Docusaurus drops it.OLake, so every <title> ends in | OLake (docs too). Keep the rendered title at 60 characters or fewer, so the frontmatter title at about 52. If the visible H1 needs to be longer, add seo_title: "..." (about 52 characters) to the frontmatter: it replaces only <title>, og:title and twitter:title, and the H1 keeps title. Docs titles under 25 characters get their sidebar section appended automatically. Code: src/theme/seo/helpers.ts, src/theme/DocItem/Metadata, src/theme/BlogPostPage.description of 120 to 155 characters (max 160, min 100), unique across the site. Do not copy one post's description into another, and do not leave it truncated with "...". Files in docs/shared are snippets and have no frontmatter.noindex, follow: confirmation pages, archive pages, tag and author pagination, zero-post authors, /search/. The theme does this for the generated pages; add it yourself to any new thank-you or utility page. Keep them crawlable (no robots.txt block), otherwise Google never sees the tag.git add . # stage all changes
git commit -m "Message" # commit
git commit -am "Message" # add + commit tracked files
git pull # fetch & merge
git push # push current branch
git branch # list branches
git status # show working tree status
git checkout -b <new-branch> # create and switch
git switch <branch> # switch existing branch
git push --set-upstream origin <branch-name>
# 1. Make sure local master is current
git switch master
git pull origin master
# 2. Create a feature branch
git checkout -b blog/your-slug # or docs/your-topic, etc.
# 3. Work on your changes
# (add blog MDX, images, authors.yml, sidebar entry, etc.)
# 4. Stage & commit
git add .
git commit -m "Add <your-slug> blog to OLake docs"
# 5. Push and open a PR
git push --set-upstream origin blog/your-slug
Finish work on the first branch and push.
Ensure master is up to date:
git switch master
git pull origin master
Create your next branch:
git checkout -b blog/second-slug
Repeat the add → commit → push cycle.
Tips • Git can feel tricky—refer to official docs, blog posts, or ask in Slack. • Always branch from
masterunless directed otherwise.
Happy writing and shipping content!
unclosed-fence | Every opening code fence has a closing one |
src/theme (Blog/useBlogInstance.js). Titles carry no post count (the count made SEO audits report "title changed" on every new post). A new blog instance must be added there, or its pages fall back to the "Blog" wording. /learn/ and /compare/ are the third and fourth instances (learn-blog and compare-blog, folders learn/ and compare/): their list pages are in the sitemap, their archive, tag and author pages are not, and /<section>/page/N/ is noindex, follow. Existing comparison posts keep their /blog/ URLs. When adding a folder of posts, also update POST_DIRS in scripts/lint-content.js, CONTENT_DIRS in scripts/generate-og-images.js and the @source list in src/css/custom.css.docusaurus.config.js (tags, authors, archive, search, docs/shared, confirmation pages, pagination). docs/shared is not built as pages at all.og:type, one H1, one JSON-LD per schema. Pages under src/pages get og:type=website from src/theme/Layout; posts emit article. Emit JSON-LD with src/components/JsonLd, not <Head><script dangerouslySetInnerHTML> (Helmet drops it).