diff --git a/studio/components/layouts/ProjectLayout/LayoutHeader/LayoutHeader.tsx b/studio/components/layouts/ProjectLayout/LayoutHeader/LayoutHeader.tsx
index c7c599a6073..3abe0aead41 100644
--- a/studio/components/layouts/ProjectLayout/LayoutHeader/LayoutHeader.tsx
+++ b/studio/components/layouts/ProjectLayout/LayoutHeader/LayoutHeader.tsx
@@ -2,7 +2,8 @@ import Link from 'next/link'
import { observer } from 'mobx-react-lite'
import { IS_PLATFORM, PRICING_TIER_PRODUCT_IDS } from 'lib/constants'
-import { useFlag, useParams, useStore } from 'hooks'
+import { useFlag, useStore } from 'hooks'
+import { useParams } from 'common/hooks'
import BreadcrumbsView from './BreadcrumbsView'
import OrgDropdown from './OrgDropdown'
import ProjectDropdown from './ProjectDropdown'
diff --git a/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.tsx b/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.tsx
index 599436d22ac..3d534b80502 100644
--- a/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.tsx
+++ b/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.tsx
@@ -13,7 +13,7 @@ import {
generateToolRoutes,
} from './NavigationBar.utils'
import NavigationIconButton from './NavigationIconButton'
-import { useParams } from 'hooks/misc/useParams'
+import { useParams } from 'common/hooks'
interface Props {}
diff --git a/studio/components/layouts/ProjectLayout/ProjectContext.tsx b/studio/components/layouts/ProjectLayout/ProjectContext.tsx
index 0c7b2144f31..aa78d0ac3ad 100644
--- a/studio/components/layouts/ProjectLayout/ProjectContext.tsx
+++ b/studio/components/layouts/ProjectLayout/ProjectContext.tsx
@@ -1,4 +1,5 @@
-import { useParams, useStore } from 'hooks'
+import { useStore } from 'hooks'
+import { useParams } from 'common/hooks'
import { observer } from 'mobx-react-lite'
import { createContext, PropsWithChildren, useContext, useMemo } from 'react'
import { Project } from 'types'
diff --git a/studio/components/layouts/ProjectLayout/ProjectLayout.tsx b/studio/components/layouts/ProjectLayout/ProjectLayout.tsx
index 8169fd225be..71a37032b0f 100644
--- a/studio/components/layouts/ProjectLayout/ProjectLayout.tsx
+++ b/studio/components/layouts/ProjectLayout/ProjectLayout.tsx
@@ -2,7 +2,8 @@ import Head from 'next/head'
import { FC, ReactNode, PropsWithChildren, Fragment } from 'react'
import { observer } from 'mobx-react-lite'
import { useRouter } from 'next/router'
-import { useStore, withAuth, useFlag, useParams } from 'hooks'
+import { useStore, withAuth, useFlag } from 'hooks'
+import { useParams } from 'common/hooks'
import { PROJECT_STATUS } from 'lib/constants'
import Connecting from 'components/ui/Loading'
diff --git a/studio/components/layouts/ProjectLayout/UpgradingState/UpgradingState.tsx b/studio/components/layouts/ProjectLayout/UpgradingState/UpgradingState.tsx
index 561f596c4c0..fbfacac365a 100644
--- a/studio/components/layouts/ProjectLayout/UpgradingState/UpgradingState.tsx
+++ b/studio/components/layouts/ProjectLayout/UpgradingState/UpgradingState.tsx
@@ -15,7 +15,8 @@ import {
} from 'ui'
import { DatabaseUpgradeStatus } from '@supabase/shared-types/out/events'
-import { useParams, useStore } from 'hooks'
+import { useStore } from 'hooks'
+import { useParams } from 'common/hooks'
import { IS_PLATFORM } from 'lib/constants'
import { DATABASE_UPGRADE_MESSAGES } from './UpgradingState.constants'
import { useProjectUpgradingStatusQuery } from 'data/config/project-upgrade-status-query'
diff --git a/studio/components/layouts/StorageLayout/StorageLayout.tsx b/studio/components/layouts/StorageLayout/StorageLayout.tsx
index cb46bbb60d2..45cc14d9aa1 100644
--- a/studio/components/layouts/StorageLayout/StorageLayout.tsx
+++ b/studio/components/layouts/StorageLayout/StorageLayout.tsx
@@ -3,7 +3,8 @@ import { useRouter } from 'next/router'
import { find, filter, get as _get } from 'lodash'
import { observer } from 'mobx-react-lite'
-import { useParams, useStore, withAuth } from 'hooks'
+import { useStore, withAuth } from 'hooks'
+import { useParams } from 'common/hooks'
import { AutoApiService, useProjectApiQuery } from 'data/config/project-api-query'
import BaseLayout from 'components/layouts'
import ProjectLayout from '../ProjectLayout/ProjectLayout'
diff --git a/studio/components/layouts/StorageLayout/StorageMenu.tsx b/studio/components/layouts/StorageLayout/StorageMenu.tsx
index be1575b9caa..ab998bb3a17 100644
--- a/studio/components/layouts/StorageLayout/StorageMenu.tsx
+++ b/studio/components/layouts/StorageLayout/StorageMenu.tsx
@@ -6,7 +6,8 @@ import * as Tooltip from '@radix-ui/react-tooltip'
import { Button, Menu, IconLoader, Alert, IconEdit } from 'ui'
import { PermissionAction } from '@supabase/shared-types/out/constants'
-import { checkPermissions, useParams } from 'hooks'
+import { checkPermissions } from 'hooks'
+import { useParams } from 'common/hooks'
import BucketRow from './BucketRow'
import { useStorageStore } from 'localStores/storageExplorer/StorageExplorerStore'
diff --git a/studio/components/layouts/TableEditorLayout/TableEditorLayout.tsx b/studio/components/layouts/TableEditorLayout/TableEditorLayout.tsx
index bd25b07380e..09e50969b71 100644
--- a/studio/components/layouts/TableEditorLayout/TableEditorLayout.tsx
+++ b/studio/components/layouts/TableEditorLayout/TableEditorLayout.tsx
@@ -4,7 +4,8 @@ import { noop } from 'lodash'
import { observer } from 'mobx-react-lite'
import { PermissionAction } from '@supabase/shared-types/out/constants'
-import { checkPermissions, useParams, useStore } from 'hooks'
+import { checkPermissions, useStore } from 'hooks'
+import { useParams } from 'common/hooks'
import { Entity } from 'data/entity-types/entity-type-query'
import { ENTITY_TYPE } from 'data/entity-types/entity-type-constants'
import ProjectLayout from '../ProjectLayout/ProjectLayout'
diff --git a/studio/components/layouts/TableEditorLayout/TableEditorMenu.tsx b/studio/components/layouts/TableEditorLayout/TableEditorMenu.tsx
index 2ad3668090f..f8e875ee90b 100644
--- a/studio/components/layouts/TableEditorLayout/TableEditorMenu.tsx
+++ b/studio/components/layouts/TableEditorLayout/TableEditorMenu.tsx
@@ -25,8 +25,9 @@ import * as Tooltip from '@radix-ui/react-tooltip'
import { PermissionAction } from '@supabase/shared-types/out/constants'
import type { PostgresSchema } from '@supabase/postgres-meta'
+import { useParams } from 'common/hooks'
import { BASE_PATH } from 'lib/constants'
-import { checkPermissions, useStore, useParams, useLocalStorage } from 'hooks'
+import { checkPermissions, useStore, useLocalStorage } from 'hooks'
import ProductMenuItem from 'components/ui/ProductMenu/ProductMenuItem'
import { useEntityTypesQuery } from 'data/entity-types/entity-types-infinite-query'
import { ENTITY_TYPE } from 'data/entity-types/entity-type-constants'
diff --git a/studio/components/to-be-cleaned/Docs/Pages/Tables/Introduction.tsx b/studio/components/to-be-cleaned/Docs/Pages/Tables/Introduction.tsx
index ba2441ad011..28723badb85 100644
--- a/studio/components/to-be-cleaned/Docs/Pages/Tables/Introduction.tsx
+++ b/studio/components/to-be-cleaned/Docs/Pages/Tables/Introduction.tsx
@@ -1,6 +1,6 @@
import { FC } from 'react'
import Link from 'next/link'
-import { useParams } from 'hooks'
+import { useParams } from 'common/hooks'
import CodeSnippet from '../../CodeSnippet'
import GeneratingTypes from 'components/interfaces/Docs/GeneratingTypes'
diff --git a/studio/components/ui/OveragesBanner/OveragesBanner.tsx b/studio/components/ui/OveragesBanner/OveragesBanner.tsx
index 991c9a05b86..5b0d0b73edf 100644
--- a/studio/components/ui/OveragesBanner/OveragesBanner.tsx
+++ b/studio/components/ui/OveragesBanner/OveragesBanner.tsx
@@ -2,7 +2,7 @@ import Link from 'next/link'
import { FC } from 'react'
import { Alert, Button } from 'ui'
-import { useParams } from 'hooks'
+import { useParams } from 'common/hooks'
import { PRICING_TIER_PRODUCT_IDS } from 'lib/constants'
import { getResourcesApproachingLimits, getResourcesExceededLimits } from './OveragesBanner.utils'
import { useProjectUsageQuery } from 'data/usage/project-usage-query'
diff --git a/studio/components/ui/ProjectSettings/DisplayApiSettings.tsx b/studio/components/ui/ProjectSettings/DisplayApiSettings.tsx
index 587e742a41a..e1bebe6e641 100644
--- a/studio/components/ui/ProjectSettings/DisplayApiSettings.tsx
+++ b/studio/components/ui/ProjectSettings/DisplayApiSettings.tsx
@@ -5,7 +5,8 @@ import { IconAlertCircle, IconLoader, Input } from 'ui'
import Panel from 'components/ui/Panel'
import { useProjectSettingsQuery } from 'data/config/project-settings-query'
import { useJwtSecretUpdatingStatusQuery } from 'data/config/jwt-secret-updating-status-query'
-import { checkPermissions, useParams } from 'hooks'
+import { checkPermissions } from 'hooks'
+import { useParams } from 'common/hooks'
import { DEFAULT_PROJECT_API_SERVICE_ID } from 'lib/constants'
const DisplayApiSettings = () => {
diff --git a/studio/components/ui/ProjectSettings/DisplayConfigSettings.tsx b/studio/components/ui/ProjectSettings/DisplayConfigSettings.tsx
index 70f1c5eba57..5c36f018f4f 100644
--- a/studio/components/ui/ProjectSettings/DisplayConfigSettings.tsx
+++ b/studio/components/ui/ProjectSettings/DisplayConfigSettings.tsx
@@ -2,7 +2,7 @@ import { JwtSecretUpdateStatus } from '@supabase/shared-types/out/events'
import Panel from 'components/ui/Panel'
import { useJwtSecretUpdatingStatusQuery } from 'data/config/jwt-secret-updating-status-query'
import { useProjectSettingsQuery } from 'data/config/project-settings-query'
-import { useParams } from 'hooks'
+import { useParams } from 'common/hooks'
import { DEFAULT_PROJECT_API_SERVICE_ID } from 'lib/constants'
import { FC } from 'react'
import { IconAlertCircle, IconLoader, Input } from 'ui'
diff --git a/studio/components/ui/ProjectUpgradeFailedBanner.tsx b/studio/components/ui/ProjectUpgradeFailedBanner.tsx
index 19bab87189a..807b17f7620 100644
--- a/studio/components/ui/ProjectUpgradeFailedBanner.tsx
+++ b/studio/components/ui/ProjectUpgradeFailedBanner.tsx
@@ -2,7 +2,7 @@ import dayjs from 'dayjs'
import Link from 'next/link'
import { useState } from 'react'
import { Alert, Button, IconX } from 'ui'
-import { useParams } from 'hooks'
+import { useParams } from 'common/hooks'
import { IS_PLATFORM } from 'lib/constants'
import { useProjectUpgradingStatusQuery } from 'data/config/project-upgrade-status-query'
import { DatabaseUpgradeStatus } from '@supabase/shared-types/out/events'
diff --git a/studio/components/ui/UpgradeToPro.tsx b/studio/components/ui/UpgradeToPro.tsx
index 81ba2eedb2d..47259e9f7b7 100644
--- a/studio/components/ui/UpgradeToPro.tsx
+++ b/studio/components/ui/UpgradeToPro.tsx
@@ -4,7 +4,8 @@ import Link from 'next/link'
import { FC, ReactNode } from 'react'
import * as Tooltip from '@radix-ui/react-tooltip'
-import { checkPermissions, useStore, useFlag, useParams } from 'hooks'
+import { checkPermissions, useStore, useFlag } from 'hooks'
+import { useParams } from 'common/hooks'
import { PRICING_TIER_PRODUCT_IDS } from 'lib/constants'
import { PermissionAction } from '@supabase/shared-types/out/constants'
diff --git a/studio/hooks/index.ts b/studio/hooks/index.ts
index bcfb55c58e7..83e5a772641 100644
--- a/studio/hooks/index.ts
+++ b/studio/hooks/index.ts
@@ -2,7 +2,6 @@ export * from './misc/useStore'
export * from './misc/withAuth'
export * from './misc/useOptimisticSqlSnippetCreate'
export * from './misc/useImmutableValue'
-export * from './misc/useParams'
export * from './misc/useCheckPermissions'
export * from './misc/useLocalStorage'
export * from './deprecated'
diff --git a/studio/hooks/misc/useUpgradePrompt.tsx b/studio/hooks/misc/useUpgradePrompt.tsx
index f19f090c302..f58aca0c45d 100644
--- a/studio/hooks/misc/useUpgradePrompt.tsx
+++ b/studio/hooks/misc/useUpgradePrompt.tsx
@@ -1,5 +1,5 @@
import { useEffect, useState } from 'react'
-import { useParams } from 'hooks'
+import { useParams } from 'common/hooks'
import { maybeShowUpgradePrompt } from 'components/interfaces/Settings/Logs'
import { useProjectSubscriptionQuery } from 'data/subscriptions/project-subscription-query'
diff --git a/studio/hooks/misc/withAuth.tsx b/studio/hooks/misc/withAuth.tsx
index e2c0ddcc643..35c36197825 100644
--- a/studio/hooks/misc/withAuth.tsx
+++ b/studio/hooks/misc/withAuth.tsx
@@ -3,7 +3,8 @@ import { useRouter } from 'next/router'
import { ComponentType, useEffect } from 'react'
import { usePermissionsQuery } from 'data/permissions/permissions-query'
-import { useParams, useStore } from 'hooks'
+import { useStore } from 'hooks'
+import { useParams } from 'common/hooks'
import { useAuth } from 'lib/auth'
import { IS_PLATFORM } from 'lib/constants'
import { getReturnToPath, STORAGE_KEY } from 'lib/gotrue'
diff --git a/studio/pages/new/[slug].tsx b/studio/pages/new/[slug].tsx
index 52b630ad0a2..67305391615 100644
--- a/studio/pages/new/[slug].tsx
+++ b/studio/pages/new/[slug].tsx
@@ -21,7 +21,8 @@ import {
PRICING_TIER_FREE_KEY,
PRICING_TIER_PRODUCT_IDS,
} from 'lib/constants'
-import { useStore, useFlag, withAuth, checkPermissions, useParams } from 'hooks'
+import { useStore, useFlag, withAuth, checkPermissions } from 'hooks'
+import { useParams } from 'common/hooks'
import { useFreeProjectLimitCheckQuery } from 'data/organizations/free-project-limit-check-query'
import { WizardLayoutWithoutAuth } from 'components/layouts'
diff --git a/studio/pages/org/[slug]/billing.tsx b/studio/pages/org/[slug]/billing.tsx
index b8510f913f3..83c44735b40 100644
--- a/studio/pages/org/[slug]/billing.tsx
+++ b/studio/pages/org/[slug]/billing.tsx
@@ -3,7 +3,8 @@ import { observer } from 'mobx-react-lite'
import { Tabs } from 'ui'
import { NextPageWithLayout } from 'types'
-import { useParams, useStore } from 'hooks'
+import { useStore } from 'hooks'
+import { useParams } from 'common/hooks'
import Loading from 'components/ui/Loading'
import { OrganizationLayout } from 'components/layouts'
import { BillingSettings } from 'components/interfaces/Organization'
diff --git a/studio/pages/org/[slug]/general.tsx b/studio/pages/org/[slug]/general.tsx
index 43cd730e8a2..f07415ba47e 100644
--- a/studio/pages/org/[slug]/general.tsx
+++ b/studio/pages/org/[slug]/general.tsx
@@ -3,7 +3,8 @@ import { observer } from 'mobx-react-lite'
import { Tabs } from 'ui'
import { NextPageWithLayout } from 'types'
-import { useParams, useStore } from 'hooks'
+import { useStore } from 'hooks'
+import { useParams } from 'common/hooks'
import Loading from 'components/ui/Loading'
import { OrganizationLayout } from 'components/layouts'
import { GeneralSettings } from 'components/interfaces/Organization'
diff --git a/studio/pages/org/[slug]/invoices.tsx b/studio/pages/org/[slug]/invoices.tsx
index f6ee9ee7eae..5ccf1ebc825 100644
--- a/studio/pages/org/[slug]/invoices.tsx
+++ b/studio/pages/org/[slug]/invoices.tsx
@@ -3,7 +3,8 @@ import { observer } from 'mobx-react-lite'
import { Tabs } from 'ui'
import { NextPageWithLayout } from 'types'
-import { useParams, useStore } from 'hooks'
+import { useStore } from 'hooks'
+import { useParams } from 'common/hooks'
import Loading from 'components/ui/Loading'
import { OrganizationLayout } from 'components/layouts'
import { InvoicesSettings } from 'components/interfaces/Organization'
diff --git a/studio/pages/org/[slug]/team.tsx b/studio/pages/org/[slug]/team.tsx
index f90d16a6486..7f96623cd61 100644
--- a/studio/pages/org/[slug]/team.tsx
+++ b/studio/pages/org/[slug]/team.tsx
@@ -3,7 +3,8 @@ import { observer } from 'mobx-react-lite'
import { Tabs } from 'ui'
import { NextPageWithLayout } from 'types'
-import { useParams, useStore } from 'hooks'
+import { useStore } from 'hooks'
+import { useParams } from 'common/hooks'
import Loading from 'components/ui/Loading'
import { OrganizationLayout } from 'components/layouts'
import { TeamSettings } from 'components/interfaces/Organization'
diff --git a/studio/pages/project/[ref]/api/graphiql.tsx b/studio/pages/project/[ref]/api/graphiql.tsx
index 5317b8e57eb..a719540f4c8 100644
--- a/studio/pages/project/[ref]/api/graphiql.tsx
+++ b/studio/pages/project/[ref]/api/graphiql.tsx
@@ -3,7 +3,8 @@ import { observer } from 'mobx-react-lite'
import { createGraphiQLFetcher, Fetcher } from '@graphiql/toolkit'
import { NextPageWithLayout } from 'types'
-import { useParams, useStore } from 'hooks'
+import { useParams } from 'common/hooks'
+import { useStore } from 'hooks'
import { API_URL, IS_PLATFORM } from 'lib/constants'
import ExtensionCard from 'components/interfaces/Database/Extensions/ExtensionCard'
import GraphiQL from 'components/interfaces/GraphQL/GraphiQL'
diff --git a/studio/pages/project/[ref]/api/index.tsx b/studio/pages/project/[ref]/api/index.tsx
index 3ceb55c3383..a890cfd8de3 100644
--- a/studio/pages/project/[ref]/api/index.tsx
+++ b/studio/pages/project/[ref]/api/index.tsx
@@ -3,7 +3,8 @@ import { FC, createContext, useContext, useEffect, useState } from 'react'
import { observer, useLocalObservable } from 'mobx-react-lite'
import { NextPageWithLayout } from 'types'
-import { checkPermissions, useParams, useStore } from 'hooks'
+import { checkPermissions, useStore } from 'hooks'
+import { useParams } from 'common/hooks'
import { snakeToCamel } from 'lib/helpers'
import { useProjectApiQuery } from 'data/config/project-api-query'
import { DocsLayout } from 'components/layouts'
diff --git a/studio/pages/project/[ref]/auth/policies.tsx b/studio/pages/project/[ref]/auth/policies.tsx
index 3d4b440d580..5fe4fc3171b 100644
--- a/studio/pages/project/[ref]/auth/policies.tsx
+++ b/studio/pages/project/[ref]/auth/policies.tsx
@@ -6,7 +6,8 @@ import { PostgresTable, PostgresPolicy } from '@supabase/postgres-meta'
import { PermissionAction } from '@supabase/shared-types/out/constants'
import { NextPageWithLayout } from 'types'
-import { checkPermissions, useParams, useStore } from 'hooks'
+import { checkPermissions, useStore } from 'hooks'
+import { useParams } from 'common/hooks'
import { AuthLayout } from 'components/layouts'
import { Policies } from 'components/interfaces/Auth/Policies'
import NoPermission from 'components/ui/NoPermission'
diff --git a/studio/pages/project/[ref]/auth/url-configuration.tsx b/studio/pages/project/[ref]/auth/url-configuration.tsx
index fd7ced97616..b0415afb0c9 100644
--- a/studio/pages/project/[ref]/auth/url-configuration.tsx
+++ b/studio/pages/project/[ref]/auth/url-configuration.tsx
@@ -7,7 +7,7 @@ import { useStore, checkPermissions } from 'hooks'
import { AuthLayout } from 'components/layouts'
import NoPermission from 'components/ui/NoPermission'
-import RedirectDomains from 'components/interfaces/Auth/RedirectDomains/RedirectDomains'
+import RedirectUrls from 'components/interfaces/Auth/RedirectUrls/RedirectUrls'
import { FormsContainer } from 'components/ui/Forms'
import SiteUrl from 'components/interfaces/Auth/SiteUrl/SiteUrl'
@@ -26,7 +26,7 @@ const URLConfiguration: NextPageWithLayout = () => {
return (
-
+
)
} else {
diff --git a/studio/pages/project/[ref]/editor/[id].tsx b/studio/pages/project/[ref]/editor/[id].tsx
index 9fd9ca0e2dc..f9c3996736a 100644
--- a/studio/pages/project/[ref]/editor/[id].tsx
+++ b/studio/pages/project/[ref]/editor/[id].tsx
@@ -7,7 +7,8 @@ import { isUndefined, isNaN } from 'lodash'
import { Alert, Button, Checkbox, IconExternalLink, Modal } from 'ui'
import type { PostgresTable, PostgresColumn } from '@supabase/postgres-meta'
-import { useStore, withAuth, useUrlState, useParams } from 'hooks'
+import { useStore, withAuth, useUrlState } from 'hooks'
+import { useParams } from 'common/hooks'
import { entityTypeKeys } from 'data/entity-types/keys'
import { Entity } from 'data/entity-types/entity-type-query'
import { Dictionary } from 'components/grid'
diff --git a/studio/pages/project/[ref]/functions/[functionSlug]/index.tsx b/studio/pages/project/[ref]/functions/[functionSlug]/index.tsx
index 156a1da2897..403f83ceec8 100644
--- a/studio/pages/project/[ref]/functions/[functionSlug]/index.tsx
+++ b/studio/pages/project/[ref]/functions/[functionSlug]/index.tsx
@@ -5,7 +5,8 @@ import { Button } from 'ui'
import { observer } from 'mobx-react-lite'
import { PermissionAction } from '@supabase/shared-types/out/constants'
-import { checkPermissions, useParams } from 'hooks'
+import { checkPermissions } from 'hooks'
+import { useParams } from 'common/hooks'
import { ChartIntervals, NextPageWithLayout } from 'types'
import { DATE_FORMAT } from 'lib/constants'
import Panel from 'components/ui/Panel'
diff --git a/studio/pages/project/[ref]/functions/[functionSlug]/invocations.tsx b/studio/pages/project/[ref]/functions/[functionSlug]/invocations.tsx
index 3fc638aa7c2..16e179787e9 100644
--- a/studio/pages/project/[ref]/functions/[functionSlug]/invocations.tsx
+++ b/studio/pages/project/[ref]/functions/[functionSlug]/invocations.tsx
@@ -1,7 +1,7 @@
import { observer } from 'mobx-react-lite'
import { NextPageWithLayout } from 'types'
-import { useParams } from 'hooks'
+import { useParams } from 'common/hooks'
import LogsPreviewer from 'components/interfaces/Settings/Logs/LogsPreviewer'
import FunctionsLayout from 'components/layouts/FunctionsLayout'
import { useEdgeFunctionQuery } from 'data/edge-functions/edge-function-query'
diff --git a/studio/pages/project/[ref]/functions/[functionSlug]/logs.tsx b/studio/pages/project/[ref]/functions/[functionSlug]/logs.tsx
index fd9510aee15..404985c654a 100644
--- a/studio/pages/project/[ref]/functions/[functionSlug]/logs.tsx
+++ b/studio/pages/project/[ref]/functions/[functionSlug]/logs.tsx
@@ -1,6 +1,6 @@
import { observer } from 'mobx-react-lite'
import { NextPageWithLayout } from 'types'
-import { useParams } from 'hooks'
+import { useParams } from 'common/hooks'
import LogsPreviewer from 'components/interfaces/Settings/Logs/LogsPreviewer'
import FunctionsLayout from 'components/layouts/FunctionsLayout'
import { useEdgeFunctionQuery } from 'data/edge-functions/edge-function-query'
diff --git a/studio/pages/project/[ref]/functions/index.tsx b/studio/pages/project/[ref]/functions/index.tsx
index e78b41e0996..0673931084f 100644
--- a/studio/pages/project/[ref]/functions/index.tsx
+++ b/studio/pages/project/[ref]/functions/index.tsx
@@ -1,6 +1,6 @@
import { observer } from 'mobx-react-lite'
-import { useParams } from 'hooks'
+import { useParams } from 'common/hooks'
import { NextPageWithLayout } from 'types'
import Table from 'components/to-be-cleaned/Table'
import FunctionsLayout from 'components/layouts/FunctionsLayout'
diff --git a/studio/pages/project/[ref]/index.tsx b/studio/pages/project/[ref]/index.tsx
index b6bd9ded124..44249b8cb22 100644
--- a/studio/pages/project/[ref]/index.tsx
+++ b/studio/pages/project/[ref]/index.tsx
@@ -1,6 +1,7 @@
import { observer } from 'mobx-react-lite'
-import { useParams, useStore } from 'hooks'
+import { useStore } from 'hooks'
+import { useParams } from 'common/hooks'
import { NextPageWithLayout } from 'types'
import { IS_PLATFORM, PROJECT_STATUS } from 'lib/constants'
import { ProjectLayoutWithAuth } from 'components/layouts'
diff --git a/studio/pages/project/[ref]/logs/explorer/index.tsx b/studio/pages/project/[ref]/logs/explorer/index.tsx
index a781fb52c3b..a45ba94cdc3 100644
--- a/studio/pages/project/[ref]/logs/explorer/index.tsx
+++ b/studio/pages/project/[ref]/logs/explorer/index.tsx
@@ -4,7 +4,8 @@ import { useRouter } from 'next/router'
import { observer } from 'mobx-react-lite'
import { Input, Modal, Form, Button } from 'ui'
-import { useParams, useStore } from 'hooks'
+import { useStore } from 'hooks'
+import { useParams } from 'common/hooks'
import useLogsQuery from 'hooks/analytics/useLogsQuery'
import { useProjectSubscriptionQuery } from 'data/subscriptions/project-subscription-query'
import { NextPageWithLayout, UserContent } from 'types'
diff --git a/studio/pages/project/[ref]/reports/api-overview.tsx b/studio/pages/project/[ref]/reports/api-overview.tsx
index 00c45d7888b..9a2a9f8a60c 100644
--- a/studio/pages/project/[ref]/reports/api-overview.tsx
+++ b/studio/pages/project/[ref]/reports/api-overview.tsx
@@ -18,10 +18,10 @@ import ReportHeader from 'components/interfaces/Reports/ReportHeader'
import { DatePickerToFrom, LogsEndpointParams } from 'components/interfaces/Settings/Logs'
import ReportFilterBar from 'components/interfaces/Reports/ReportFilterBar'
import { useProjectSubscriptionQuery } from 'data/subscriptions/project-subscription-query'
-import { useParams } from 'hooks'
+import { useParams } from 'common/hooks'
import { isEqual } from 'lodash'
import ShimmerLine from 'components/ui/ShimmerLine'
-import ReportPadding from "components/interfaces/Reports/ReportPadding"
+import ReportPadding from 'components/interfaces/Reports/ReportPadding'
export const ApiReport: NextPageWithLayout = () => {
const { ref: projectRef } = useParams()
diff --git a/studio/pages/project/[ref]/reports/database.tsx b/studio/pages/project/[ref]/reports/database.tsx
index 51ff8dfb946..ae7c16394cb 100644
--- a/studio/pages/project/[ref]/reports/database.tsx
+++ b/studio/pages/project/[ref]/reports/database.tsx
@@ -3,7 +3,8 @@ import { observer } from 'mobx-react-lite'
import { FC, useEffect, useState } from 'react'
import { Badge, Button, IconArrowRight, IconExternalLink } from 'ui'
-import { useParams, useStore } from 'hooks'
+import { useStore } from 'hooks'
+import { useParams } from 'common/hooks'
import {
PRICING_TIER_PRODUCT_IDS,
TIME_PERIODS_INFRA,
diff --git a/studio/pages/project/[ref]/reports/index.tsx b/studio/pages/project/[ref]/reports/index.tsx
index aece220eb06..dfda77f3db6 100644
--- a/studio/pages/project/[ref]/reports/index.tsx
+++ b/studio/pages/project/[ref]/reports/index.tsx
@@ -4,7 +4,8 @@ import { useRouter } from 'next/router'
import { PermissionAction } from '@supabase/shared-types/out/constants'
import { NextPageWithLayout } from 'types'
-import { checkPermissions, useFlag, useParams, useStore } from 'hooks'
+import { checkPermissions, useFlag, useStore } from 'hooks'
+import { useParams } from 'common/hooks'
import { post } from 'lib/common/fetch'
import { API_URL, PROJECT_STATUS } from 'lib/constants'
import { useProjectContentStore } from 'stores/projectContentStore'
diff --git a/studio/pages/project/[ref]/settings/api.tsx b/studio/pages/project/[ref]/settings/api.tsx
index 288127c97a6..0446e3d361a 100644
--- a/studio/pages/project/[ref]/settings/api.tsx
+++ b/studio/pages/project/[ref]/settings/api.tsx
@@ -2,7 +2,8 @@ import { createContext } from 'react'
import { useRouter } from 'next/router'
import { observer, useLocalObservable } from 'mobx-react-lite'
-import { useParams, useStore } from 'hooks'
+import { useStore } from 'hooks'
+import { useParams } from 'common/hooks'
import { NextPageWithLayout } from 'types'
import { SettingsLayout } from 'components/layouts'
import ServiceList from 'components/interfaces/Settings/API/ServiceList'
diff --git a/studio/pages/project/[ref]/settings/database.tsx b/studio/pages/project/[ref]/settings/database.tsx
index 026f211e571..d9b90a1cecb 100644
--- a/studio/pages/project/[ref]/settings/database.tsx
+++ b/studio/pages/project/[ref]/settings/database.tsx
@@ -1,6 +1,7 @@
import { observer } from 'mobx-react-lite'
import { NextPageWithLayout } from 'types'
-import { useFlag, useParams } from 'hooks'
+import { useFlag } from 'hooks'
+import { useParams } from 'common/hooks'
import { SettingsLayout } from 'components/layouts'
import {
ConnectionPooling,
diff --git a/studio/pages/project/[ref]/settings/storage.tsx b/studio/pages/project/[ref]/settings/storage.tsx
index 7f2f2c15180..0ac1df2ea45 100644
--- a/studio/pages/project/[ref]/settings/storage.tsx
+++ b/studio/pages/project/[ref]/settings/storage.tsx
@@ -2,7 +2,8 @@ import React, { useEffect } from 'react'
import { observer } from 'mobx-react-lite'
import { API_URL, PROJECT_STATUS } from 'lib/constants'
-import { useFlag, useParams, useStore } from 'hooks'
+import { useFlag, useStore } from 'hooks'
+import { useParams } from 'common/hooks'
import { post } from 'lib/common/fetch'
import { SettingsLayout } from 'components/layouts'
import { StorageSettings } from 'components/to-be-cleaned/Storage'
diff --git a/studio/pages/project/[ref]/settings/vault/keys.tsx b/studio/pages/project/[ref]/settings/vault/keys.tsx
index 530c5b2fb3d..1b14ead4e9a 100644
--- a/studio/pages/project/[ref]/settings/vault/keys.tsx
+++ b/studio/pages/project/[ref]/settings/vault/keys.tsx
@@ -3,7 +3,8 @@ import { useRouter } from 'next/router'
import { observer } from 'mobx-react-lite'
import { Tabs } from 'ui'
-import { useParams, useStore } from 'hooks'
+import { useStore } from 'hooks'
+import { useParams } from 'common/hooks'
import { NextPageWithLayout } from 'types'
import { SettingsLayout } from 'components/layouts'
import { VaultToggle, EncryptionKeysManagement } from 'components/interfaces/Settings/Vault'
diff --git a/studio/pages/project/[ref]/settings/vault/secrets.tsx b/studio/pages/project/[ref]/settings/vault/secrets.tsx
index 4a7a92ebb33..8b50c447ac0 100644
--- a/studio/pages/project/[ref]/settings/vault/secrets.tsx
+++ b/studio/pages/project/[ref]/settings/vault/secrets.tsx
@@ -3,7 +3,8 @@ import { useRouter } from 'next/router'
import { observer } from 'mobx-react-lite'
import { Tabs } from 'ui'
-import { useParams, useStore } from 'hooks'
+import { useStore } from 'hooks'
+import { useParams } from 'common/hooks'
import { NextPageWithLayout } from 'types'
import { SettingsLayout } from 'components/layouts'
import { VaultToggle, SecretsManagement } from 'components/interfaces/Settings/Vault'
diff --git a/studio/pages/project/[ref]/storage/buckets/index.tsx b/studio/pages/project/[ref]/storage/buckets/index.tsx
index 396a914ba2a..8f4ad3bba21 100644
--- a/studio/pages/project/[ref]/storage/buckets/index.tsx
+++ b/studio/pages/project/[ref]/storage/buckets/index.tsx
@@ -3,7 +3,8 @@ import { useRouter } from 'next/router'
import { observer } from 'mobx-react-lite'
import { API_URL } from 'lib/constants'
-import { useFlag, useParams, useStore } from 'hooks'
+import { useFlag, useStore } from 'hooks'
+import { useParams } from 'common/hooks'
import { post } from 'lib/common/fetch'
import { PROJECT_STATUS } from 'lib/constants'
import { StorageLayout } from 'components/layouts'
diff --git a/studio/stores/authConfig/schema/AuthProviders/AuthProvidersFormValidation.tsx b/studio/stores/authConfig/schema/AuthProviders/AuthProvidersFormValidation.tsx
index 084c21c0fcf..d5b9ece9210 100644
--- a/studio/stores/authConfig/schema/AuthProviders/AuthProvidersFormValidation.tsx
+++ b/studio/stores/authConfig/schema/AuthProviders/AuthProvidersFormValidation.tsx
@@ -1,5 +1,5 @@
import { boolean, number, object, string } from 'yup'
-import { domainRegex } from 'components/interfaces/Auth/Auth.constants'
+import { urlRegex } from 'components/interfaces/Auth/Auth.constants'
const JSON_SCHEMA_VERSION = 'http://json-schema.org/draft-07/schema#'
@@ -385,7 +385,7 @@ const EXTERNAL_PROVIDER_AZURE = {
then: (schema) => schema.required('Secret ID is required'),
otherwise: (schema) => schema,
}),
- EXTERNAL_AZURE_URL: string().matches(domainRegex, 'Must be a valid URL').optional(),
+ EXTERNAL_AZURE_URL: string().matches(urlRegex, 'Must be a valid URL').optional(),
}),
misc: {
iconKey: 'microsoft-icon',
@@ -583,7 +583,7 @@ const EXTERNAL_PROVIDER_GITLAB = {
then: (schema) => schema.required('Client Secret is required'),
otherwise: (schema) => schema,
}),
- EXTERNAL_GITLAB_URL: string().matches(domainRegex, 'Must be a valid URL').optional(),
+ EXTERNAL_GITLAB_URL: string().matches(urlRegex, 'Must be a valid URL').optional(),
}),
misc: {
iconKey: 'gitlab-icon',
@@ -671,8 +671,8 @@ const EXTERNAL_PROVIDER_KEYCLOAK = {
EXTERNAL_KEYCLOAK_URL: string().when('EXTERNAL_KEYCLOAK_ENABLED', {
is: true,
then: (schema) =>
- schema.matches(domainRegex, 'Must be a valid URL').required('Realm URL is required'),
- otherwise: (schema) => schema.matches(domainRegex, 'Must be a valid URL'),
+ schema.matches(urlRegex, 'Must be a valid URL').required('Realm URL is required'),
+ otherwise: (schema) => schema.matches(urlRegex, 'Must be a valid URL'),
}),
}),
misc: {
@@ -937,7 +937,7 @@ const EXTERNAL_PROVIDER_WORKOS = {
validationSchema: object().shape({
EXTERNAL_WORKOS_ENABLED: boolean().required(),
EXTERNAL_WORKOS_URL: string()
- .matches(domainRegex, 'Must be a valid URL')
+ .matches(urlRegex, 'Must be a valid URL')
.when('EXTERNAL_WORKOS_ENABLED', {
is: true,
then: (schema) => schema.required('WorkOS URL is required'),
diff --git a/studio/tests/components/Auth/Auth.constants.test.js b/studio/tests/components/Auth/Auth.constants.test.js
index 4c8a3fe62f3..ab7504014dc 100644
--- a/studio/tests/components/Auth/Auth.constants.test.js
+++ b/studio/tests/components/Auth/Auth.constants.test.js
@@ -1,87 +1,87 @@
-import { domainRegex } from 'components/interfaces/Auth/Auth.constants'
+import { urlRegex } from 'components/interfaces/Auth/Auth.constants'
describe('Auth.constants: domainRegex', () => {
test('should validate typical URLs', () => {
const mockInput1 = 'http://domain.com'
- const output1 = domainRegex.test(mockInput1)
+ const output1 = urlRegex.test(mockInput1)
expect(output1).toBe(true)
const mockInput2 = 'https://supabase.io'
- const output2 = domainRegex.test(mockInput2)
+ const output2 = urlRegex.test(mockInput2)
expect(output2).toBe(true)
const mockInput3 = 'https://new-domain-vercel.com'
- const output3 = domainRegex.test(mockInput3)
+ const output3 = urlRegex.test(mockInput3)
expect(output3).toBe(true)
const mockInput4 = 'www.test-domain.com'
- const output4 = domainRegex.test(mockInput4)
+ const output4 = urlRegex.test(mockInput4)
expect(output4).toBe(true)
})
test('should validate app-based domains', () => {
const mockInput1 = 'exp://exp.host/some-app'
- const output1 = domainRegex.test(mockInput1)
+ const output1 = urlRegex.test(mockInput1)
expect(output1).toBe(true)
const mockInput2 = 'exp://exp.host/some-app?release-channel=default'
- const output2 = domainRegex.test(mockInput2)
+ const output2 = urlRegex.test(mockInput2)
expect(output2).toBe(true)
})
test('should validate subdomains', () => {
const mockInput1 = 'https://app.supabase.com'
- const output1 = domainRegex.test(mockInput1)
+ const output1 = urlRegex.test(mockInput1)
expect(output1).toBe(true)
})
test('should validate localhost URLs', () => {
const mockInput1 = 'http://localhost:3000'
- const output1 = domainRegex.test(mockInput1)
+ const output1 = urlRegex.test(mockInput1)
expect(output1).toBe(true)
})
test('should validate URLs with query params', () => {
const mockInput1 = 'https://supabase.com?name=test'
- const output1 = domainRegex.test(mockInput1)
+ const output1 = urlRegex.test(mockInput1)
expect(output1).toBe(true)
const mockInput2 = 'https://supabase.com?name=test&description=hello&page=2'
- const output2 = domainRegex.test(mockInput2)
+ const output2 = urlRegex.test(mockInput2)
expect(output2).toBe(true)
})
test('should validate URLs with wildcards', () => {
const mockInput1 = 'https://supabase*.com'
- const output1 = domainRegex.test(mockInput1)
+ const output1 = urlRegex.test(mockInput1)
expect(output1).toBe(true)
const mockInput2 = 'https://supabase.com/*'
- const output2 = domainRegex.test(mockInput2)
+ const output2 = urlRegex.test(mockInput2)
expect(output2).toBe(true)
const mockInput3 = 'https://new-*-domain.com/*'
- const output3 = domainRegex.test(mockInput3)
+ const output3 = urlRegex.test(mockInput3)
expect(output3).toBe(true)
const mockInput4 = 'https://new-*-domain.com/*/*/*'
- const output4 = domainRegex.test(mockInput4)
+ const output4 = urlRegex.test(mockInput4)
expect(output4).toBe(true)
const mockInput5 = 'https://sub-*-domain.new-*-domain.com/*/*/*'
- const output5 = domainRegex.test(mockInput5)
+ const output5 = urlRegex.test(mockInput5)
expect(output5).toBe(true)
})
test('should invalidate invalid URLs', () => {
const mockInput1 = 'supabase'
- const output1 = domainRegex.test(mockInput1)
+ const output1 = urlRegex.test(mockInput1)
expect(output1).toBe(false)
const mockInput2 = 'mailto:test@gmail.com'
- const output2 = domainRegex.test(mockInput2)
+ const output2 = urlRegex.test(mockInput2)
expect(output2).toBe(false)
const mockInput4 = 'hello world.com'
- const output4 = domainRegex.test(mockInput4)
+ const output4 = urlRegex.test(mockInput4)
expect(output4).toBe(false)
const mockInput5 = 'email@domain.com'
- const output5 = domainRegex.test(mockInput5)
+ const output5 = urlRegex.test(mockInput5)
expect(output5).toBe(false)
})
})
diff --git a/studio/tests/pages/projects/LogsPreviewer.test.js b/studio/tests/pages/projects/LogsPreviewer.test.js
index 15774d0b66c..780a82f9d4a 100644
--- a/studio/tests/pages/projects/LogsPreviewer.test.js
+++ b/studio/tests/pages/projects/LogsPreviewer.test.js
@@ -23,7 +23,8 @@ import userEvent from '@testing-library/user-event'
import { wait } from '@testing-library/user-event/dist/utils'
import { logDataFixture } from '../../fixtures'
import { LogsTableName } from 'components/interfaces/Settings/Logs'
-import { useParams } from 'hooks'
+jest.mock('common/hooks')
+import { useParams } from 'common/hooks'
beforeEach(() => {
// reset mocks between tests
diff --git a/studio/tests/pages/projects/logs-query.test.js b/studio/tests/pages/projects/logs-query.test.js
index 378b62c6f02..eb1ce4d5c50 100644
--- a/studio/tests/pages/projects/logs-query.test.js
+++ b/studio/tests/pages/projects/logs-query.test.js
@@ -8,7 +8,8 @@ import { logDataFixture } from '../../fixtures'
import { clickDropdown } from 'tests/helpers'
import dayjs from 'dayjs'
import { useProjectSubscriptionQuery } from 'data/subscriptions/project-subscription-query'
-import { useParams } from 'hooks'
+jest.mock('common/hooks')
+import { useParams } from 'common/hooks'
const defaultRouterMock = () => {
const router = jest.fn()
diff --git a/turbo.json b/turbo.json
index 176ef881d41..3ca755f081d 100644
--- a/turbo.json
+++ b/turbo.json
@@ -4,6 +4,43 @@
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**"]
},
+ "www#build": {
+ "dependsOn": ["^build"],
+ "env": [
+ "SUPABASE_SERVICE_ROLE_SECRET",
+ "EMAIL_TO_ID_SECRET",
+ "SUPABASE_URL",
+ "GITHUB_OAUTH_CLIENT_SECRET"
+ ],
+ "outputs": [".next/**", "!.next/cache/**"]
+ },
+ "docs#build": {
+ "dependsOn": ["^build"],
+ "env": ["SUPABASE_SERVICE_ROLE_KEY", "OPENAI_KEY", "ALGOLIA_SEARCH_ADMIN_KEY"],
+ "outputs": [".next/**", "!.next/cache/**"]
+ },
+ "studio#build": {
+ "dependsOn": ["^build"],
+ "env": [
+ "SITE_URL",
+ "AUTH0_AUDIENCE",
+ "AUTH0_CLIENT_ID",
+ "AUTH0_CLIENT_SECRET",
+ "AUTH0_DOMAIN",
+ "COOKIE_DOMAIN",
+ "INTERCOM_API_KEY",
+ "READ_ONLY_API_KEY",
+ "READ_ONLY_URL",
+ "SENTRY_AUTH_TOKEN",
+ "SENTRY_ORG",
+ "SENTRY_PROJECT",
+ "SENTRY_URL",
+ "SESSION_COOKIE_SECRET",
+ "SUPABASE_ENCRYPTION_KEY",
+ "PLATFORM_PG_META_URL"
+ ],
+ "outputs": [".next/**", "!.next/cache/**"]
+ },
"lint": {
"outputs": []
},