diff --git a/.github/workflows/docs-lint-v2.yml b/.github/workflows/docs-lint-v2.yml
new file mode 100644
index 00000000000..31cfe6ea4fd
--- /dev/null
+++ b/.github/workflows/docs-lint-v2.yml
@@ -0,0 +1,44 @@
+name: '[Docs] Lint v2'
+on:
+ pull_request:
+ paths:
+ - '.github/workflows/docs-lint-v2.yml'
+ - 'supa-mdx-lint.config.toml'
+ - 'apps/docs/content/**'
+
+env:
+ CARGO_NET_GIT_FETCH_WITH_CLI: true
+
+jobs:
+ supa-mdx-lint:
+ name: supa-mdx-lint
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ sparse-checkout: |
+ supa-mdx-lint.config.toml
+ apps/docs/content
+ - name: cache cargo
+ id: cache-cargo
+ uses: actions/cache@v4
+ with:
+ path: |
+ ~/.cargo/bin/
+ ~/.cargo/registry/index/
+ ~/.cargo/registry/cache/
+ ~/.cargo/git/db/
+ key: 9fd8c8fa7487a3d454a676e6e3d7409af34fc715
+ - name: install linter
+ if: steps.cache-cargo.outputs.cache-hit != 'true'
+ run: cargo install --locked --git https://github.com/supabase-community/supa-mdx-lint --rev 9fd8c8fa7487a3d454a676e6e3d7409af34fc715
+ - name: install reviewdog
+ uses: reviewdog/action-setup@3f401fe1d58fe77e10d665ab713057375e39b887 # v1.3.0
+ with:
+ reviewdog_version: v0.20.2
+ - name: run linter
+ env:
+ REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ set -o pipefail
+ supa-mdx-lint apps/docs/content/guides/getting-started --format rdf | reviewdog -f=rdjsonl -reporter=github-pr-review
diff --git a/.github/workflows/lint-prose.yml b/.github/workflows/lint-prose.yml
index 160985e74f0..a652acb37c3 100644
--- a/.github/workflows/lint-prose.yml
+++ b/.github/workflows/lint-prose.yml
@@ -27,4 +27,5 @@ jobs:
echo "CHANGED_FILES=$(git diff --name-only --diff-filter=ACMRT origin/$BASE_REF $SHA | grep '^apps/docs/content/' | tr '\n' ',' | sed 's/,$//')" >> $GITHUB_OUTPUT
- uses: errata-ai/vale-action@reviewdog
with:
- files: ${{ steps.changed-files.outputs.CHANGED_FILES }}
+ files: '${{ steps.changed-files.outputs.CHANGED_FILES }}'
+ separator: ','
diff --git a/apps/docs/content/guides/getting-started/features.mdx b/apps/docs/content/guides/getting-started/features.mdx
index 6a982ddec9a..fdc5bfda954 100644
--- a/apps/docs/content/guides/getting-started/features.mdx
+++ b/apps/docs/content/guides/getting-started/features.mdx
@@ -16,7 +16,7 @@ Every project is a full Postgres database. [Docs](/docs/guides/database).
Store vector embeddings right next to the rest of your data. [Docs](/docs/guides/ai).
-### Auto-generated Rest API via PostgREST
+### Auto-generated REST API via PostgREST
RESTful APIs are auto-generated from your database, without a single line of code. [Docs](/docs/guides/api#rest-api-overview).
@@ -66,13 +66,13 @@ Deploy read-only databases across multiple regions, for lower latency and better
Launch the Supabase stack on Fly.io edge network. [Docs](/docs/guides/platform/fly-postgres).
-### Log Drains
+### Log drains
Export Supabase logs at to 3rd party providers and external tooling. [Docs](/docs/guides/platform/log-drains).
## Studio
-### Studio Single Sign On
+### Studio Single Sign-On
Login to the Supabase dashboard via SSO. [Docs](/docs/guides/platform/sso).
@@ -118,7 +118,7 @@ Control the data each user can access with Postgres Policies. [Docs](/docs/guide
Add Captcha to your sign-in, sign-up, and password reset forms. [Docs](/docs/guides/auth/auth-captcha).
-### Server-side Auth
+### Server-Side Auth
Helpers for implementing user authentication in popular server-side languages and frameworks like Next.js, SvelteKit and Remix. [Docs](/docs/guides/auth/server-side).
@@ -183,11 +183,11 @@ Unofficial libraries are supported by the community.
Supabase Features are in 4 different states - Private Alpha, Public Alpha, Beta and Generally Available.
-### Private Alpha
+### Private alpha
Features are initially launched as a private alpha to gather feedback from the community. To join our early access program, send an email to product-ops@supabase.io.
-### Public Alpha
+### Public alpha
The alpha stage indicates that the API might change in the future, not that the service isn’t stable. Even though the [uptime Service Level Agreement](https://supabase.com/sla) does not cover products in Alpha, we do our best to have the service as stable as possible.
@@ -195,7 +195,7 @@ The alpha stage indicates that the API might change in the future, not that the
Features in Beta are tested by an external penetration tester for security issues. The API is guaranteed to be stable and there is a strict communication process for breaking changes.
-### Generally Available
+### Generally available
In addition to the Beta requirements, features in GA are covered by the [uptime SLA](https://supabase.com/sla).
diff --git a/apps/docs/content/guides/getting-started/tutorials/with-kotlin.mdx b/apps/docs/content/guides/getting-started/tutorials/with-kotlin.mdx
index 513a651444d..4f9a0527b1e 100644
--- a/apps/docs/content/guides/getting-started/tutorials/with-kotlin.mdx
+++ b/apps/docs/content/guides/getting-started/tutorials/with-kotlin.mdx
@@ -96,6 +96,8 @@ plugins {
}
```
+{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
+
### Set up Hilt for dependency injection
In the `build.gradle` (app) file, add the following:
@@ -134,6 +136,8 @@ class MainActivity : ComponentActivity() {
}
```
+{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
+
### Provide Supabase instances with Hilt
To make the app easier to test, create a `SupabaseModule.kt` file as follows:
diff --git a/apps/docs/content/guides/getting-started/tutorials/with-nextjs.mdx b/apps/docs/content/guides/getting-started/tutorials/with-nextjs.mdx
index d43d01b8ab5..277a212022f 100644
--- a/apps/docs/content/guides/getting-started/tutorials/with-nextjs.mdx
+++ b/apps/docs/content/guides/getting-started/tutorials/with-nextjs.mdx
@@ -301,7 +301,7 @@ meta="utils/supabase/middleware.ts"
## Set up a login page
-### Login and Signup form
+### Login and signup form
Create a login/signup page for your application:
diff --git a/apps/docs/content/guides/getting-started/tutorials/with-refine.mdx b/apps/docs/content/guides/getting-started/tutorials/with-refine.mdx
index 0192a305f14..f3a901e69a6 100644
--- a/apps/docs/content/guides/getting-started/tutorials/with-refine.mdx
+++ b/apps/docs/content/guides/getting-started/tutorials/with-refine.mdx
@@ -97,7 +97,7 @@ You can find the full contents of this file [here](https://raw.githubusercontent
In order for us to add login and user profile pages in this App, we have to tweak the `` component inside `App.tsx`.
-### The `` Component
+### The `` component
The `App.tsx` file initially looks like this:
diff --git a/apps/docs/content/guides/getting-started/tutorials/with-swift.mdx b/apps/docs/content/guides/getting-started/tutorials/with-swift.mdx
index 33e597d1210..fe6999a3f94 100644
--- a/apps/docs/content/guides/getting-started/tutorials/with-swift.mdx
+++ b/apps/docs/content/guides/getting-started/tutorials/with-swift.mdx
@@ -293,6 +293,8 @@ Update the entry point to the newly created `AppView`. Run in Xcode to launch yo
Every Supabase project is configured with [Storage](/docs/guides/storage) for managing large files like
photos and videos.
+{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
+
### Add PhotosPicker
Let's add support for the user to pick an image from the library and upload it.
@@ -332,6 +334,8 @@ enum TransferError: Error {
}
```
+{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
+
#### Add PhotosPicker to profile page
```swift ProfileView.swift
diff --git a/package.json b/package.json
index 82a14eb6657..e9361b69657 100644
--- a/package.json
+++ b/package.json
@@ -5,7 +5,12 @@
"author": "Supabase, Inc.",
"license": "Apache-2.0",
"private": true,
- "workspaces": ["apps/*", "tests", "playwright-tests", "packages/*"],
+ "workspaces": [
+ "apps/*",
+ "tests",
+ "playwright-tests",
+ "packages/*"
+ ],
"scripts": {
"build": "turbo run build",
"build:studio": "turbo run build --filter=studio",
@@ -53,6 +58,13 @@
"npm": "^10.0.0",
"node": "^20.0.0"
},
- "keywords": ["postgres", "firebase", "storage", "functions", "database", "auth"],
+ "keywords": [
+ "postgres",
+ "firebase",
+ "storage",
+ "functions",
+ "database",
+ "auth"
+ ],
"packageManager": "npm@10.7.0"
}
diff --git a/supa-mdx-lint.config.toml b/supa-mdx-lint.config.toml
new file mode 100644
index 00000000000..1eba0db28cc
--- /dev/null
+++ b/supa-mdx-lint.config.toml
@@ -0,0 +1,48 @@
+ignore_patterns = ["**/_*.mdx"]
+
+# Heading should be sentence case
+[Rule001HeadingCase]
+# Words that may be uppercased even if they are not the first word in the sentence.
+# Can also specify a regex that is compatible with the [Rust regex crate](https://docs.rs/regex/latest/regex/).
+may_uppercase = [
+ "[A-Z]{3,5}",
+ "Android",
+ "Angular",
+ "Apple",
+ "Auth",
+ "Content Delivery Network",
+ "Dart",
+ "Edge Functions",
+ "Flutter",
+ "GoTrue",
+ "Google",
+ "GraphQL",
+ "Ionic Angular",
+ "Ionic React",
+ "Ionic Vue",
+ "JavaScript",
+ "Kotlin",
+ "Next.js",
+ "Nuxt",
+ "OpenAI",
+ "Postgres",
+ "PostgreSQL",
+ "PostgREST",
+ "React",
+ "React Native",
+ "RedwoodJS",
+ "Row Level Security",
+ "Server-Side Auth",
+ "Single Sign-On",
+ "SolidJS",
+ "Supabase",
+ "Svelte",
+ "SvelteKit",
+ "Swift",
+ "SwiftUI",
+ "Xcode",
+ "Vue",
+]
+# Words that may be lowercased even if they are the first word in the sentence.
+# Can also specify a regex that is compatible with the [Rust regex crate](https://docs.rs/regex/latest/regex/).
+may_lowercase = []
diff --git a/vale/styles/Custom/Headings.yml b/vale/styles/Custom/Headings.yml
deleted file mode 100644
index beb9022e6a5..00000000000
--- a/vale/styles/Custom/Headings.yml
+++ /dev/null
@@ -1,37 +0,0 @@
-extends: capitalization
-message: "'%s' should use sentence-style capitalization."
-link: "https://developers.google.com/style/capitalization#capitalization-in-titles-and-headings"
-level: warning
-scope: heading
-match: $sentence
-indicators:
- - ":"
-exceptions:
- - API
- - Azure
- - ChatGPT
- - ChatGPT Retrieval Plugin
- - CLI
- - Cosmos
- - Docker
- - Edge Functions?
- - Emmet
- - gRPC
- - HNSW
- - I
- - JWT
- - Kubernetes
- - Linux
- - macOS
- - Marketplace
- - MongoDB
- - OpenAI
- - REPL
- - REST
- - Studio
- - Transformers.js
- - TypeScript
- - URLs
- - Visual
- - VS
- - Windows
diff --git a/vale/styles/Custom/WordList.yml b/vale/styles/Custom/WordList.yml
deleted file mode 100644
index dfcb9f1f9d9..00000000000
--- a/vale/styles/Custom/WordList.yml
+++ /dev/null
@@ -1,90 +0,0 @@
-extends: substitution
-message: "Use '%s' instead of '%s'."
-link: 'https://developers.google.com/style/word-list'
-level: warning
-ignorecase: false
-action:
- name: replace
-swap:
- '(?:API Console|dev|developer) key': API key
- '(?:cell ?phone|smart ?phone)': phone|mobile phone
- '(?:dev|developer|APIs) console': API console
- '(?:e-mail|Email|E-mail)': email
- '(?:file ?path|path ?name)': path
- '(?:kill|terminate|abort)': stop|exit|cancel|end
- '(?:Nginx|nginx)': NGINX
- '(?:OAuth ?2|Oauth)': OAuth 2.0
- '(?:ok|Okay)': OK|okay
- '(?:WiFi|wifi)': Wi-Fi
- '(?i)postgresql': Postgres
- '[\.]+apk': APK
- '3\-D': 3D
- 'Google (?:I\-O|IO)': Google I/O
- 'Next(?:js)?': Next.js (if referring to the framework)
- 'tap (?:&|and) hold': touch & hold
- 'un(?:check|select)': clear
- 'utili[sz](?:e[ds]|ing)': use, used, uses, etc.
- above: preceding
- account name: username
- action bar: app bar
- Ajax: AJAX
- a\.k\.a|aka: or|also known as
- Android device: Android-powered device
- android: Android
- API explorer: APIs Explorer
- approx\.: approximately
- authN: authentication
- authZ: authorization
- autogenerated: auto-generated
- autoupdate: automatically update
- cellular data: mobile data
- cellular network: mobile network
- chapter: documents|pages|sections
- check box: checkbox
- check: select
- click on: click|click in
- Cloud: Google Cloud Platform|GCP
- Container Engine: Kubernetes Engine
- content type: media type
- curated roles: predefined roles
- data are: data is
- Developers Console: Google API Console|API Console
- disabled?: turn off|off
- ephemeral IP address: ephemeral external IP address
- fewer data: less data
- file name: filename
- firewalls: firewall rules
- functionality: capability|feature
- Github: GitHub
- Google account: Google Account
- Google accounts: Google Accounts
- Googling: search with Google
- grayed-out: unavailable
- head over to: go to|see
- HTTPs: HTTPS
- in order to: to
- ingest: import|load
- k8s: Kubernetes
- long press: touch & hold
- network IP address: internal IP address
- omnibox: address bar
- open-source: open source
- overview screen: recents screen
- regex: regular expression
- refer to: see
- serverside: server-side
- SHA1: SHA-1|HAS-SHA1
- sign into: sign in to
- sign-ins?: signin(s) (noun) or sign in (verb)
- sign-?on: single sign-on
- sign-outs?: signout(s) (noun) or sign out (verb)
- sign-ups?: signup(s) (noun) or sign up (verb)
- static IP address: static external IP address
- stylesheet: style sheet
- synch: sync
- tablename: table name
- tablet: device
- touch: tap
- url: URL
- vs\.: versus
- World Wide Web: web