diff --git a/apps/docs/components/Favicons.tsx b/apps/docs/components/Favicons.tsx index 5c65346f0fa..1e9ddafffe1 100644 --- a/apps/docs/components/Favicons.tsx +++ b/apps/docs/components/Favicons.tsx @@ -5,32 +5,46 @@ const Favicons = () => { const { basePath } = useRouter() return ( - - - - - {/* */} - + {/* prettier-ignore */} + + {/* prettier-ignore */} + + {/* prettier-ignore */} + + {/* prettier-ignore */} + + {/* prettier-ignore */} + + {/* prettier-ignore */} + + {/* prettier-ignore */} + + {/* prettier-ignore */} + + {/* prettier-ignore */} + - + + + + + - + - + {/* misc */} + + + ) } diff --git a/apps/docs/pages/guides/auth/auth-helpers/sveltekit.mdx b/apps/docs/pages/guides/auth/auth-helpers/sveltekit.mdx index 5ffe6f1b488..7350cb786a4 100644 --- a/apps/docs/pages/guides/auth/auth-helpers/sveltekit.mdx +++ b/apps/docs/pages/guides/auth/auth-helpers/sveltekit.mdx @@ -367,7 +367,6 @@ protect multiple routes at once. ```ts // src/hooks.server.ts import type { RequestHandler } from './$types'; -import { getSupabase } from '@supabase/auth-helpers-sveltekit'; import { redirect, error } from '@sveltejs/kit'; export const handle: Handle = async ({ event, resolve }) => { diff --git a/apps/docs/public/favicon/android-chrome-192x192.png b/apps/docs/public/favicon/android-chrome-192x192.png index f45e47c8a9c..f0a2817a744 100644 Binary files a/apps/docs/public/favicon/android-chrome-192x192.png and b/apps/docs/public/favicon/android-chrome-192x192.png differ diff --git a/apps/docs/public/favicon/android-chrome-512x512.png b/apps/docs/public/favicon/android-chrome-512x512.png index 3a0ba2b52aa..1c658733e6e 100644 Binary files a/apps/docs/public/favicon/android-chrome-512x512.png and b/apps/docs/public/favicon/android-chrome-512x512.png differ diff --git a/apps/docs/public/favicon/apple-touch-icon-114x114.png b/apps/docs/public/favicon/apple-touch-icon-114x114.png new file mode 100644 index 00000000000..d2ee4b9e139 Binary files /dev/null and b/apps/docs/public/favicon/apple-touch-icon-114x114.png differ diff --git a/apps/docs/public/favicon/apple-touch-icon-120x120.png b/apps/docs/public/favicon/apple-touch-icon-120x120.png new file mode 100644 index 00000000000..5bd0e4963a1 Binary files /dev/null and b/apps/docs/public/favicon/apple-touch-icon-120x120.png differ diff --git a/apps/docs/public/favicon/apple-touch-icon-144x144.png b/apps/docs/public/favicon/apple-touch-icon-144x144.png new file mode 100644 index 00000000000..c73891c985d Binary files /dev/null and b/apps/docs/public/favicon/apple-touch-icon-144x144.png differ diff --git a/apps/docs/public/favicon/apple-touch-icon-152x152.png b/apps/docs/public/favicon/apple-touch-icon-152x152.png new file mode 100644 index 00000000000..65f90a02357 Binary files /dev/null and b/apps/docs/public/favicon/apple-touch-icon-152x152.png differ diff --git a/apps/docs/public/favicon/apple-touch-icon-57x57.png b/apps/docs/public/favicon/apple-touch-icon-57x57.png new file mode 100644 index 00000000000..bfa1628afb5 Binary files /dev/null and b/apps/docs/public/favicon/apple-touch-icon-57x57.png differ diff --git a/apps/docs/public/favicon/apple-touch-icon-60x60.png b/apps/docs/public/favicon/apple-touch-icon-60x60.png new file mode 100644 index 00000000000..15c5dca8005 Binary files /dev/null and b/apps/docs/public/favicon/apple-touch-icon-60x60.png differ diff --git a/apps/docs/public/favicon/apple-touch-icon-72x72.png b/apps/docs/public/favicon/apple-touch-icon-72x72.png new file mode 100644 index 00000000000..fb0c4fb3663 Binary files /dev/null and b/apps/docs/public/favicon/apple-touch-icon-72x72.png differ diff --git a/apps/docs/public/favicon/apple-touch-icon-76x76.png b/apps/docs/public/favicon/apple-touch-icon-76x76.png new file mode 100644 index 00000000000..7d950f0862e Binary files /dev/null and b/apps/docs/public/favicon/apple-touch-icon-76x76.png differ diff --git a/apps/docs/public/favicon/apple-touch-icon.png b/apps/docs/public/favicon/apple-touch-icon.png deleted file mode 100644 index 330e352fa5f..00000000000 Binary files a/apps/docs/public/favicon/apple-touch-icon.png and /dev/null differ diff --git a/apps/docs/public/favicon/archive/android-chrome-192x192.png b/apps/docs/public/favicon/archive/android-chrome-192x192.png new file mode 100644 index 00000000000..c0ac2bb1cdb Binary files /dev/null and b/apps/docs/public/favicon/archive/android-chrome-192x192.png differ diff --git a/apps/docs/public/favicon/archive/android-chrome-512x512.png b/apps/docs/public/favicon/archive/android-chrome-512x512.png new file mode 100644 index 00000000000..4de626fcc9e Binary files /dev/null and b/apps/docs/public/favicon/archive/android-chrome-512x512.png differ diff --git a/apps/docs/public/favicon/archive/apple-touch-icon-114x114.png b/apps/docs/public/favicon/archive/apple-touch-icon-114x114.png new file mode 100644 index 00000000000..4aa46d4d25d Binary files /dev/null and b/apps/docs/public/favicon/archive/apple-touch-icon-114x114.png differ diff --git a/apps/docs/public/favicon/archive/apple-touch-icon-120x120.png b/apps/docs/public/favicon/archive/apple-touch-icon-120x120.png new file mode 100644 index 00000000000..d2b0e50ef41 Binary files /dev/null and b/apps/docs/public/favicon/archive/apple-touch-icon-120x120.png differ diff --git a/apps/docs/public/favicon/archive/apple-touch-icon-144x144.png b/apps/docs/public/favicon/archive/apple-touch-icon-144x144.png new file mode 100644 index 00000000000..00a5d8b5180 Binary files /dev/null and b/apps/docs/public/favicon/archive/apple-touch-icon-144x144.png differ diff --git a/apps/docs/public/favicon/archive/apple-touch-icon-152x152.png b/apps/docs/public/favicon/archive/apple-touch-icon-152x152.png new file mode 100644 index 00000000000..310532c4648 Binary files /dev/null and b/apps/docs/public/favicon/archive/apple-touch-icon-152x152.png differ diff --git a/apps/docs/public/favicon/archive/apple-touch-icon-57x57.png b/apps/docs/public/favicon/archive/apple-touch-icon-57x57.png new file mode 100644 index 00000000000..1314e02c744 Binary files /dev/null and b/apps/docs/public/favicon/archive/apple-touch-icon-57x57.png differ diff --git a/apps/docs/public/favicon/archive/apple-touch-icon-60x60.png b/apps/docs/public/favicon/archive/apple-touch-icon-60x60.png new file mode 100644 index 00000000000..0615675e809 Binary files /dev/null and b/apps/docs/public/favicon/archive/apple-touch-icon-60x60.png differ diff --git a/apps/docs/public/favicon/archive/apple-touch-icon-72x72.png b/apps/docs/public/favicon/archive/apple-touch-icon-72x72.png new file mode 100644 index 00000000000..e4418058cef Binary files /dev/null and b/apps/docs/public/favicon/archive/apple-touch-icon-72x72.png differ diff --git a/apps/docs/public/favicon/archive/apple-touch-icon-76x76.png b/apps/docs/public/favicon/archive/apple-touch-icon-76x76.png new file mode 100644 index 00000000000..9a76327f94b Binary files /dev/null and b/apps/docs/public/favicon/archive/apple-touch-icon-76x76.png differ diff --git a/apps/docs/public/favicon/archive/favicon-128.png b/apps/docs/public/favicon/archive/favicon-128.png new file mode 100644 index 00000000000..d5dca345802 Binary files /dev/null and b/apps/docs/public/favicon/archive/favicon-128.png differ diff --git a/apps/docs/public/favicon/archive/favicon-16x16.png b/apps/docs/public/favicon/archive/favicon-16x16.png new file mode 100644 index 00000000000..6361bcecd15 Binary files /dev/null and b/apps/docs/public/favicon/archive/favicon-16x16.png differ diff --git a/apps/docs/public/favicon/archive/favicon-196x196.png b/apps/docs/public/favicon/archive/favicon-196x196.png new file mode 100644 index 00000000000..adb05b43453 Binary files /dev/null and b/apps/docs/public/favicon/archive/favicon-196x196.png differ diff --git a/apps/docs/public/favicon/archive/favicon-32x32.png b/apps/docs/public/favicon/archive/favicon-32x32.png new file mode 100644 index 00000000000..4ea0fba2e3c Binary files /dev/null and b/apps/docs/public/favicon/archive/favicon-32x32.png differ diff --git a/apps/docs/public/favicon/archive/favicon-96x96.png b/apps/docs/public/favicon/archive/favicon-96x96.png new file mode 100644 index 00000000000..92a3d735dff Binary files /dev/null and b/apps/docs/public/favicon/archive/favicon-96x96.png differ diff --git a/apps/docs/public/favicon/archive/favicon.ico b/apps/docs/public/favicon/archive/favicon.ico new file mode 100644 index 00000000000..4e808093c05 Binary files /dev/null and b/apps/docs/public/favicon/archive/favicon.ico differ diff --git a/apps/docs/public/favicon/archive/mstile-144x144.png b/apps/docs/public/favicon/archive/mstile-144x144.png new file mode 100644 index 00000000000..00a5d8b5180 Binary files /dev/null and b/apps/docs/public/favicon/archive/mstile-144x144.png differ diff --git a/apps/docs/public/favicon/archive/mstile-150x150.png b/apps/docs/public/favicon/archive/mstile-150x150.png new file mode 100644 index 00000000000..4de1d9b1cc1 Binary files /dev/null and b/apps/docs/public/favicon/archive/mstile-150x150.png differ diff --git a/apps/docs/public/favicon/archive/mstile-310x150.png b/apps/docs/public/favicon/archive/mstile-310x150.png new file mode 100644 index 00000000000..b1121df62aa Binary files /dev/null and b/apps/docs/public/favicon/archive/mstile-310x150.png differ diff --git a/apps/docs/public/favicon/archive/mstile-310x310.png b/apps/docs/public/favicon/archive/mstile-310x310.png new file mode 100644 index 00000000000..7ea95ae09c0 Binary files /dev/null and b/apps/docs/public/favicon/archive/mstile-310x310.png differ diff --git a/apps/docs/public/favicon/archive/mstile-70x70.png b/apps/docs/public/favicon/archive/mstile-70x70.png new file mode 100644 index 00000000000..d5dca345802 Binary files /dev/null and b/apps/docs/public/favicon/archive/mstile-70x70.png differ diff --git a/apps/docs/public/favicon/favicon-128.png b/apps/docs/public/favicon/favicon-128.png new file mode 100644 index 00000000000..2206096f21b Binary files /dev/null and b/apps/docs/public/favicon/favicon-128.png differ diff --git a/apps/docs/public/favicon/favicon-16x16.png b/apps/docs/public/favicon/favicon-16x16.png index 4b7e28143e7..2e07b15e106 100644 Binary files a/apps/docs/public/favicon/favicon-16x16.png and b/apps/docs/public/favicon/favicon-16x16.png differ diff --git a/apps/docs/public/favicon/favicon-196x196.png b/apps/docs/public/favicon/favicon-196x196.png new file mode 100644 index 00000000000..d10fc7e36d9 Binary files /dev/null and b/apps/docs/public/favicon/favicon-196x196.png differ diff --git a/apps/docs/public/favicon/favicon-32x32.png b/apps/docs/public/favicon/favicon-32x32.png index 1a268444bf9..4101a08499b 100644 Binary files a/apps/docs/public/favicon/favicon-32x32.png and b/apps/docs/public/favicon/favicon-32x32.png differ diff --git a/apps/docs/public/favicon/favicon-96x96.png b/apps/docs/public/favicon/favicon-96x96.png new file mode 100644 index 00000000000..b23072a2c02 Binary files /dev/null and b/apps/docs/public/favicon/favicon-96x96.png differ diff --git a/apps/docs/public/favicon/favicon.ico b/apps/docs/public/favicon/favicon.ico index 5c4d1dcc5cf..51b9988fdcb 100644 Binary files a/apps/docs/public/favicon/favicon.ico and b/apps/docs/public/favicon/favicon.ico differ diff --git a/apps/docs/public/favicon/mstile-144x144.png b/apps/docs/public/favicon/mstile-144x144.png new file mode 100644 index 00000000000..c73891c985d Binary files /dev/null and b/apps/docs/public/favicon/mstile-144x144.png differ diff --git a/apps/docs/public/favicon/mstile-150x150.png b/apps/docs/public/favicon/mstile-150x150.png index 836aed416a0..bd10ae0a5df 100644 Binary files a/apps/docs/public/favicon/mstile-150x150.png and b/apps/docs/public/favicon/mstile-150x150.png differ diff --git a/apps/docs/public/favicon/mstile-310x150.png b/apps/docs/public/favicon/mstile-310x150.png new file mode 100644 index 00000000000..fb4d58022df Binary files /dev/null and b/apps/docs/public/favicon/mstile-310x150.png differ diff --git a/apps/docs/public/favicon/mstile-310x310.png b/apps/docs/public/favicon/mstile-310x310.png new file mode 100644 index 00000000000..0adc45ea0ac Binary files /dev/null and b/apps/docs/public/favicon/mstile-310x310.png differ diff --git a/apps/docs/public/favicon/mstile-70x70.png b/apps/docs/public/favicon/mstile-70x70.png new file mode 100644 index 00000000000..2206096f21b Binary files /dev/null and b/apps/docs/public/favicon/mstile-70x70.png differ diff --git a/apps/docs/public/favicon/safari-pinned-tab.svg b/apps/docs/public/favicon/safari-pinned-tab.svg deleted file mode 100644 index 7e408790eb0..00000000000 --- a/apps/docs/public/favicon/safari-pinned-tab.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - -Created by potrace 1.11, written by Peter Selinger 2001-2013 - - - - - diff --git a/apps/docs/public/favicon/site.webmanifest b/apps/docs/public/favicon/site.webmanifest index 8da2b0f3d44..c72ae95e89d 100644 --- a/apps/docs/public/favicon/site.webmanifest +++ b/apps/docs/public/favicon/site.webmanifest @@ -3,12 +3,12 @@ "short_name": "Supabase", "icons": [ { - "src": "/favicons/android-chrome-192x192.png", + "src": "/favicon/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" }, { - "src": "/favicons/android-chrome-512x512.png", + "src": "/favicon/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" } diff --git a/apps/docs/public/img/icons/menu/reference-csharp.svg b/apps/docs/public/img/icons/menu/reference-csharp.svg index 40d0375079d..84c1dcf8966 100644 --- a/apps/docs/public/img/icons/menu/reference-csharp.svg +++ b/apps/docs/public/img/icons/menu/reference-csharp.svg @@ -1,9 +1,9 @@ - - - - - - - - + + + + + + + + diff --git a/apps/docs/styles/main.scss b/apps/docs/styles/main.scss index ea1f9b78324..dedeb72ffd9 100644 --- a/apps/docs/styles/main.scss +++ b/apps/docs/styles/main.scss @@ -23,7 +23,7 @@ } body { - @apply bg-scale-100 dark:bg-[#1c1c1c] #{!important}; + @apply bg-scale-200 dark:bg-[#1c1c1c] #{!important}; scroll-behavior: smooth; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; diff --git a/apps/www/_blog/2023-04-07-launch-week-7-hackathon.mdx b/apps/www/_blog/2023-04-07-launch-week-7-hackathon.mdx index 54fb600af2b..de89693f3be 100644 --- a/apps/www/_blog/2023-04-07-launch-week-7-hackathon.mdx +++ b/apps/www/_blog/2023-04-07-launch-week-7-hackathon.mdx @@ -14,7 +14,7 @@ toc_depth: 2 With Easter just around the corner, [Launch Week](https://supabase.com/launch-week) is about to start and, as usual, we're running an async hackathon alongside it. This time it’s AI-themed! -The hackathon starts **now** and ends Monday 16th April at 11:59 pm. You can win extremily limited edition Launch Week themed mechanical keyboards and limited edition Supabase swag. +The hackathon starts **now** and ends Monday 16th April at 11:59 pm. You can win extremely limited edition Launch Week themed mechanical keyboards and limited edition Supabase swag. For some inspiration check out the [Next.js OpenAI Doc Search template](https://github.com/supabase-community/nextjs-openai-doc-search?og=v2) released yesterday and [storing embeddings on Supabase article](https://supabase.com/blog/openai-embeddings-postgres-vector). diff --git a/apps/www/_blog/2023-04-10-supabase-logs-self-hosted.mdx b/apps/www/_blog/2023-04-10-supabase-logs-self-hosted.mdx new file mode 100644 index 00000000000..6895fe84d77 --- /dev/null +++ b/apps/www/_blog/2023-04-10-supabase-logs-self-hosted.mdx @@ -0,0 +1,194 @@ +--- +title: 'Supabase Logs: open source logging server' +launchweek: 7 +tags: + - launch-week + - o11y +date: '2023-04-10' +to_depth: 3 +author: chasers,ziinc +image: launch-week-7/day-1-supabase-logs-self-hosted/day-1-supabase-logs-self-hosted-og.jpg +thumb: launch-week-7/day-1-supabase-logs-self-hosted/day-1-supabase-logs-self-hosted-thumb.jpg +--- + +Today, we’re releasing Supabase Logs for both self-hosted users and CLI development. + +
+ + _Whatch the video announcement_ +
+ +## Logflare Introduction + +Since [Logflare joined Supabase](https://supabase.com/blog/supabase-acquires-logflare) over a year ago it’s been quietly handling over 1 billion log events every day. These events come from various tools in the Supabase infrastructure - the API gateway, Postgres databases, Storage, Edge Functions, Auth, and Realtime. + +Logflare is a multi-node, highly available Elixir cluster, ingesting the log events and storing them into BigQuery for Supabase and Logflare’s customers. On average, the cluster has 6 nodes handling every spike our customers throw at it. + +To expose log data to customers, we leverage Logflare Endpoints. This provides an HTTP integration into Supabase Studio, powering the log query UIs and most time-series charts. These charts live across the studio, such as the project home page and the new API reports. + +{/* */} + +## Self-hosting Logflare + +Logflare was available under a BSL license prior to joining Supabase. We’ve since changed the license to [Apache 2.0](https://github.com/Logflare/logflare/blob/staging/LICENSE.md), aligning it with our open source philosophy. + +In the past few months we’ve made Logflare more developer-friendly for local development and self-hosting. While you’re building a project, you can view and query your logs from any Supabase service, just as you would in our cloud platform. + +![Logs UI](/images/blog/lw7-o11y/logs-screenshot.png) + +
+ +📢 Check out the [new self-hosting docs](https://supabase.com/docs/reference/self-hosting-analytics/introduction) to get Logflare up and running as your analytics server. + +
+ +It currently supports a BigQuery backend, and we are actively working on supporting more. + +## The Ingestion Pipeline + +Logflare receives Supabase log events via multiple methods. Services like Postgres use [Vector](https://vector.dev/) to clean and forward log events to the Logflare ingest API. Other services such as Realtime and Storage utilize [native Logflare integrations](https://github.com/Logflare/logflare#integrations) to send the log events directly. These then get processed and streamed into BigQuery. + +## The Querying Pipeline + +The hard part comes after ingesting the logs: searching, aggregating ,and analyzing them at scale. Crunching many terabytes of data on each query is expensive, and exposing the ingested data to Supabase customers in a naive manner would cause our costs to skyrocket. + +To solve these issues, we built and refined Logflare Endpoints, the query engine that powers many of Supabase’s features, such as the logs views, Logs Explorer, and usage charts. + +With Endpoints, you can create HTTP API endpoints from a SQL query, including parameterized queries. Endpoints are like PostgREST views but with some benefits: + +- **Query parameters** + - You can provide string parameters to the SQL query via the HTTP endpoint. +- **Read-through caching** + - Results from the query are cached in memory for fast response times. + - A read-through cache provides results if cached results do not exist. +- **Active cache warming** + - Query results are proactively warmed at a configurable interval for a combination of fast response times and as-realtime-as-needed data. +- **Query sandboxing** + - If an Endpoint query contains a CTE and the sandbox option is selected, the Endpoint will inject the query string of the `sql` query parameter into the Endpoint SQL replacing the default query (the part of the SQL query after the CTE). + - Endpoints parse SQL to allow `select` queries only. No DML or DDL statements are permitted to run through Logflare Endpoints. + +With this feature set, Supabase has been able to build any view we’ve needed on top of billions of daily log events. + +### Logflare Endpoint Example + +Using webhooks, we can send all GitHub events in the Supabase organization to Logflare. The webhook sends structured events, and Logflare transforms the payload into metadata: + +```json +{ + "event_message": "supabase/supabase | JohannesBauer97 | created", + "id": "0d48b71d-91c5-4356-82c7-fdb299b625d0", + "metadata": { + "sender": { + "id": 15695124, + "login": "JohannesBauer97", + "node_id": "MDQ6VXNlcjE1Njk1MTI0", + "site_admin": false, + "type": "User", + "url": "https://api.github.com/users/JohannesBauer97" + }, + "starred_at": "2023-03-30T20:33:55Z" + //... + }, + "timestamp": 1680208436849642 +} +``` + +We’re interested in the top contributors, which can be extracted with SQL (in BigQuery dialect): + +```sql +select + count(t.timestamp) as count, + s.login as gh_user +from + `github.supabase.webhooks` as t + cross join unnest(metadata) as m + cross join unnest(m.sender) as s +where + timestamp::date > current_date() - @day::int +group by + gh_user +order by + count desc +limit + 25 +``` + +With this view in place, we can use Endpoints to provide an API that we can hit from our application: + +```bash +curl "https://logflare.app/endpoints/query/69425db0-1cfb-48b4-84c7-2a872b6f0a61" \ + -H 'Content-Type: application/json; charset=utf-8' \ + -G -d "day=30" +``` + +This returns a JSON response with the top org wide contributors for the last 30 days! + +```json +{ + "result": [ + { "count": 23404, "gh_user": "vercel[bot]" }, + { "count": 10005, "gh_user": "joshenlim" }, + { "count": 7026, "gh_user": "MildTomato" }, + { "count": 6405, "gh_user": "fsansalvadore" }, + { "count": 5195, "gh_user": "saltcod" }, + { "count": 3454, "gh_user": "alaister" }, + { "count": 2691, "gh_user": "kevcodez" }, + { "count": 2117, "gh_user": "gregnr" }, + { "count": 1769, "gh_user": "Ziinc" }, + { "count": 1749, "gh_user": "chasers" }, + { "count": 1430, "gh_user": "Isaiah-Hamilton" } + //... + ] +} +``` + +We can configure this Endpoint to cache results for an interval of 10 minutes after the first API request, and proactively update those cached results every 2 minutes - 5 queries across the 10 minute interval. Even if we hit the Endpoint thousands of times, we only sustain the cost of 5 queries. + +The initial request is fast because Logflare also performs setup (such as partitioning) on our BigQuery tables appropriately. Subsequent requests are _extremely fast_ as they are cached in-memory. + +The best part is that all these knobs can be tweaked for your use case. If we have a real-time requirement, we can completely disable caching or reduce the proactive caching to update on a per-second interval. + +## The Self-hosted Challenge + +To change the license, we needed to remove all closed-source dependencies. Previously, Logflare relied on the closed source [General SQL Parser](https://www.sqlparser.com/) under a business licenses. This is incompatible with the Apache License. + +We switched to an open source alternative, the rust-based [sqlparser-rs](https://github.com/sqlparser-rs/sqlparser-rs) library, contributing a [few updates](https://github.com/sqlparser-rs/sqlparser-rs/pulls?q=is%3Apr+is%3Amerged+author%3AZiinc) for the BigQuery dialect. + +Along with the parser, we invested a lot of effort into transforming the multi-tenant architecture into something that was self-hosting friendly and easily configurable. We moved towards environment variable based configuration instead of compile-time configurations, exposing the Endpoints configurations necessary for Supabase Logs. + +## What’s Next? + +To further integrate Logflare into the Supabase platform, we are building out 2 main areas: Management API, Multiple Backends. + +### Management API + +The Management API allows users to interact programmatically with Logflare to manage their account and resources. This feature will be available for both Logflare customers and self-hosted users. + +You can check out the preview of our OpenAPI spec here: [https://logflare.app/swaggerui](https://logflare.app/swaggerui) + +![Swagger UI](/images/blog/lw7-o11y/swagger.png) + +Not only that, we intend to expose user account provisioning to select partners. Soon, you’ll be able to become a Logflare Partner to provision Logflare accounts through the Partner API. Perfect if you want to resell a log analytics service from your own platform. + +Contact us at growth@supabase.com to get in early on that waitlist. + +## Multiple Backends + +Logflare currently supports a BigQuery backend. We plan to add support for other analytics-optimized databases, like Clickhouse. We will also support pushing data to other web services, making Logflare a good fit for any data pipeline. + +This will benefit the Supabase CLI: once Postgres support is available, Logflare will be able to integrate seamlessly, without the BigQuery requirement. + +## Wrapping Up + +Logflare has given Supabase the flexibility to quickly deploy features powered by an underlying structured event stream. Materializing metrics from an event stream is a powerful framework for delivering real-time views on analytics streams. + +Logflare is the hub of analytics streams for Supabase. We look forward to giving Supabase customers the same superpower. diff --git a/apps/www/components/Blog/ShareArticleActions.tsx b/apps/www/components/Blog/ShareArticleActions.tsx new file mode 100644 index 00000000000..351bf951dc6 --- /dev/null +++ b/apps/www/components/Blog/ShareArticleActions.tsx @@ -0,0 +1,64 @@ +import Link from 'next/link' + +const ShareArticleActions = ({ title, slug }: { title: string; slug: string }) => ( +
+ + + + + + + + + + + + + + + + + + + + + + + +
+) + +export default ShareArticleActions diff --git a/apps/www/components/Favicons.tsx b/apps/www/components/Favicons.tsx index 5c65346f0fa..ccdf07dd37a 100644 --- a/apps/www/components/Favicons.tsx +++ b/apps/www/components/Favicons.tsx @@ -5,32 +5,47 @@ const Favicons = () => { const { basePath } = useRouter() return ( - - - - - {/* */} - + {/* prettier-ignore */} + + {/* prettier-ignore */} + + {/* prettier-ignore */} + + {/* prettier-ignore */} + + {/* prettier-ignore */} + + {/* prettier-ignore */} + + {/* prettier-ignore */} + + {/* prettier-ignore */} + + {/* prettier-ignore */} + - + + + + + - + + {/* misc */} + + + ) } diff --git a/apps/www/components/LaunchWeek/HackernewsShare.tsx b/apps/www/components/LaunchWeek/HackernewsShare.tsx new file mode 100644 index 00000000000..89ed624f49f --- /dev/null +++ b/apps/www/components/LaunchWeek/HackernewsShare.tsx @@ -0,0 +1,32 @@ +import Image from 'next/image' +import React from 'react' +import days from '~/components/LaunchWeek/lw7_days' + +const HackernewsShare = ({ url, title }: { url: string; title: string }) => { + const hackerNewsLink = `https://news.ycombinator.com/submitlink?u=${encodeURIComponent( + url + )}&t=${encodeURIComponent(title)}` + + return ( +
+

Start a conversation about this topic

+ + + + + + +
+ ) +} + +export default HackernewsShare diff --git a/apps/www/components/LaunchWeek/LaunchSection/LaunchWeekPrizeSection.tsx b/apps/www/components/LaunchWeek/LaunchSection/LaunchWeekPrizeSection.tsx index 05f73843e1e..052d6c44479 100644 --- a/apps/www/components/LaunchWeek/LaunchSection/LaunchWeekPrizeSection.tsx +++ b/apps/www/components/LaunchWeek/LaunchSection/LaunchWeekPrizeSection.tsx @@ -3,15 +3,22 @@ import LabelBadge from '../LabelBadge' import LaunchWeekPrizeCard from './LaunchWeekPrizeCard' import { motion } from 'framer-motion' -export default function LaunchWeekPrizeSection({ className }: { className?: string }) { +export default function LaunchWeekPrizeSection({ + className, + ticket, +}: { + className?: string + ticket?: any +}) { const finalAnimationState = { y: 0, opacity: 1 } + const Ticket = ticket return ( -
-
+
+
-
+ {ticket && } +
- diff --git a/apps/www/components/LaunchWeek/Releases/LW7/LW7Releases.tsx b/apps/www/components/LaunchWeek/Releases/LW7/LW7Releases.tsx index 5d221a7ff8a..a17dec5ab3b 100644 --- a/apps/www/components/LaunchWeek/Releases/LW7/LW7Releases.tsx +++ b/apps/www/components/LaunchWeek/Releases/LW7/LW7Releases.tsx @@ -30,6 +30,16 @@ const opacityVariant = { }, }, } +const opacityVariant2 = { + default: { opacity: 0, ease: defaultEase, duration: 0.2 }, + hover: { + opacity: 0.2, + transition: { + duration: 0.4, + ease: defaultEase, + }, + }, +} const scaleOpacityVariant = { default: { scale: 1, opacity: 0.9, ease: defaultEase, duration: 0.2 }, hover: { @@ -47,6 +57,28 @@ const aiImageMobileVariant = { scale: 0.9, }, } +const moveX10 = { + default: { x: 0, ease: defaultEase, duration: 0.2 }, + hover: { + x: 10, + transition: { + duration: 0.4, + ease: defaultEase, + }, + }, +} + +const getDay1Motion = (index: number) => { + switch (index) { + case 1: + case 2: + return moveX10 + case 3: + return opacityVariant2 + default: + return undefined + } +} export default function LW7Releases() { const [preRelease, day1, day2, day3, day4, day5] = days @@ -72,7 +104,7 @@ export default function LW7Releases() { return ( <> - +
- Supabase AI Hackathon is on. Join now! + Supabase AI Hackathon has begun. Join now!
-
+
Blog post
@@ -146,18 +178,15 @@ export default function LW7Releases() { Join the prize draw
-
- - Learn more -
- -
+
+ + More info
- +
{preRelease.steps[0].title} - Guide + Guide
-
+ {day1.steps.length > 0 && ( +
+ +
+ {day1.steps[0].title} + New +
+ + {day1.steps[0].bg_layers && + day1.steps[0].bg_layers?.map((layer, i) => + !!layer.lottie ? ( +
+ +
+ ) : ( + !!layer.img && ( + + + + ) + ) + )} +
+
+ )}
diff --git a/apps/www/components/LaunchWeek/Releases/LW7/components/index.tsx b/apps/www/components/LaunchWeek/Releases/LW7/components/index.tsx index f1a3c4152b8..5dee2cc9edc 100644 --- a/apps/www/components/LaunchWeek/Releases/LW7/components/index.tsx +++ b/apps/www/components/LaunchWeek/Releases/LW7/components/index.tsx @@ -83,7 +83,7 @@ export const SmallCard = ({ >
@@ -143,9 +143,26 @@ export const AccordionHeader = ({ date, day, title, shipped }: any) => { ) } -export const ChipLink = ({ href, children }: { href: string; children: any }) => ( - - +export const ChipLink = ({ + href, + className, + target, + children, +}: { + href: string + className?: string + target?: '_blank' | '_self' | '_parent' | '_top' | 'framename' + children: any +}) => ( + + {children} @@ -167,7 +184,7 @@ export const SectionButtons = ({ hackernews?: string }) => { return ( -
+
{!!blog && ( Blog post @@ -193,7 +210,7 @@ export const SectionButtons = ({ )} {!!github && ( - + View on Github
@@ -209,7 +226,7 @@ export const SectionButtons = ({ )} {hackernews && ( - + Read more
diff --git a/apps/www/components/LaunchWeek/Ticket/ActualTicket.tsx b/apps/www/components/LaunchWeek/Ticket/ActualTicket.tsx index fb8530c6a9a..0dd73115d35 100644 --- a/apps/www/components/LaunchWeek/Ticket/ActualTicket.tsx +++ b/apps/www/components/LaunchWeek/Ticket/ActualTicket.tsx @@ -42,7 +42,7 @@ export default function Ticket({ return (
= pageCount * 2 ? (i - pageCount * (offset - 1)) / 15 : i / 15 return ( - + window.scrollTo(0, 0)} + > { const { isDarkMode } = useTheme() @@ -112,7 +113,7 @@ const Nav = () => { const HamburgerButton = (props: HamburgerButtonProps) => (
props.toggleFlyOut()} >
) diff --git a/apps/www/components/ScrollProgress.tsx b/apps/www/components/ScrollProgress.tsx new file mode 100644 index 00000000000..ddbea562561 --- /dev/null +++ b/apps/www/components/ScrollProgress.tsx @@ -0,0 +1,44 @@ +import { useRouter } from 'next/router' +import React, { useEffect, useState } from 'react' + +const ScrollProgress = () => { + const [progressPercentage, setProgressPercentage] = useState(0) + const { pathname } = useRouter() + + const isBlogPost = pathname.includes('/blog/') + if (!isBlogPost) return null + + const handleScroll = () => { + if (typeof document === 'undefined') return null + const article = document?.querySelector('article') + const { top, height } = (article as any)?.getBoundingClientRect() + let scrollDistance = -top + let progressPercentage = + (scrollDistance / (height - document.documentElement.clientHeight)) * 100 + setProgressPercentage(progressPercentage) + } + + useEffect(() => { + window.addEventListener('scroll', handleScroll) + return () => { + window.removeEventListener('scroll', handleScroll) + } + }, []) + + let isActive = progressPercentage <= 100 + + return ( +
+
+
+ ) +} + +export default ScrollProgress diff --git a/apps/www/data/Pricing.json b/apps/www/data/Pricing.json index bf87270ed6f..48648187a67 100644 --- a/apps/www/data/Pricing.json +++ b/apps/www/data/Pricing.json @@ -154,6 +154,14 @@ "enterprise": "Contact Us" } }, + { + "title": "Single Sign-On (SAML 2.0)", + "tiers": { + "free": false, + "pro": "50 free, then $0.015 per MAU", + "enterprise": "Contact Us" + } + }, { "title": "Advanced security features", "tiers": { diff --git a/apps/www/hooks/useActiveAnchors.tsx b/apps/www/hooks/useActiveAnchors.tsx new file mode 100644 index 00000000000..00a48824387 --- /dev/null +++ b/apps/www/hooks/useActiveAnchors.tsx @@ -0,0 +1,49 @@ +import { useEffect, useRef } from 'react' + +const useActiveAnchors = ( + anchorsQuerySelector: string = 'h2', + tocQuerySelector: string = '.prose-toc a', + offset: number = 200 +) => { + const anchors = useRef | null>(null) + const toc = useRef | null>(null) + + const handleScroll = () => { + const pageYOffset = window.pageYOffset + let newActiveAnchor: string = '' + + anchors.current?.forEach((anchor) => { + if (pageYOffset >= anchor.offsetTop - offset) { + newActiveAnchor = anchor.id + } + }) + + toc.current?.forEach((link) => { + link.classList.remove('toc-animate') + // TODO: escape emojis + // The problem is that MDXRemote strips out emojis on slugs + // but ReactMarkdown doesn't,instead it encodes them + const sanitizedHref = (link.getAttribute('href') ?? '').replace('#', '') + const isMatch = sanitizedHref === newActiveAnchor + + if (isMatch) { + link.classList.add('toc-animate') + } + }) + } + + useEffect(() => { + anchors.current = document.querySelectorAll(anchorsQuerySelector) + toc.current = document.querySelectorAll(tocQuerySelector) + + window.addEventListener('scroll', handleScroll) + + return () => { + window.removeEventListener('scroll', handleScroll) + } + }, []) + + return null +} + +export default useActiveAnchors diff --git a/apps/www/lib/authors.json b/apps/www/lib/authors.json index 0a0a9728f2a..36396fe333a 100644 --- a/apps/www/lib/authors.json +++ b/apps/www/lib/authors.json @@ -285,5 +285,19 @@ "position": "Design", "author_url": "https://dribbble.com/marijanasimag", "author_image_url": "https://github.com/marijanasimag.png" + }, + { + "author_id": "ziinc", + "author": "Lee TzeYiing", + "position": "Engineering", + "author_url": "https://github.com/Ziinc", + "author_image_url": "https://github.com/Ziinc.png" + }, + { + "author_id": "chasers", + "author": "Chase Granberry", + "position": "Engineering", + "author_url": "https://github.com/chasers", + "author_image_url": "https://github.com/chasers.png" } ] diff --git a/apps/www/pages/_document.tsx b/apps/www/pages/_document.tsx index 8429f60254f..1aec4af5553 100644 --- a/apps/www/pages/_document.tsx +++ b/apps/www/pages/_document.tsx @@ -3,11 +3,11 @@ import Document, { Html, Head, Main, NextScript } from 'next/document' export default class MyDocument extends Document { render() { return ( - +