Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
fb353dd
fix(brand): centralize canonical site, repository, docs, and social d…
EcstaceeLOR Oct 18, 2026
185d2da
fix(brand): use one canonical product identity and community links (#…
EcstaceeLOR Oct 18, 2026
a35f074
fix(brand): replace stale repository and community links with shared …
EcstaceeLOR Oct 18, 2026
d204c7e
fix(brand): replace stale repository and community links with shared …
EcstaceeLOR Oct 18, 2026
09f2461
fix(brand): replace stale repository and community links with shared …
EcstaceeLOR Oct 18, 2026
64d9a72
fix(brand): replace stale repository and community links with shared …
EcstaceeLOR Oct 18, 2026
a507340
fix(brand): align web manifest, SEO image, and docs links with SO4 id…
EcstaceeLOR Oct 18, 2026
ad7a7e9
fix(brand): align web manifest, SEO image, and docs links with SO4 id…
EcstaceeLOR Oct 18, 2026
280e0d3
fix(brand): align web manifest, SEO image, and docs links with SO4 id…
EcstaceeLOR Oct 18, 2026
2ac4c13
fix(brand): align web manifest, SEO image, and docs links with SO4 id…
EcstaceeLOR Oct 18, 2026
54712ca
fix(brand): align web manifest, SEO image, and docs links with SO4 id…
EcstaceeLOR Oct 18, 2026
9671184
test(brand): reject stale Levee domain and GitHub links (#846)
EcstaceeLOR Oct 18, 2026
aa3014b
ci(test): run full contribution gate for issue branch
EcstaceeLOR Oct 18, 2026
65fd457
test: correct regex literals in issue-specific coverage
EcstaceeLOR Oct 18, 2026
28504d5
style(brand): align config imports with repository lint rules (#846)
EcstaceeLOR Oct 18, 2026
bf2878c
style(brand): align config imports with repository lint rules (#846)
EcstaceeLOR Oct 18, 2026
ecc9128
style(brand): align config imports with repository lint rules (#846)
EcstaceeLOR Oct 18, 2026
66e0d84
style(brand): align config imports with repository lint rules (#846)
EcstaceeLOR Oct 18, 2026
b5854de
style(brand): align config imports with repository lint rules (#846)
EcstaceeLOR Oct 18, 2026
acef1fe
style(brand): align config imports with repository lint rules (#846)
EcstaceeLOR Oct 18, 2026
a246eea
style(brand): align config imports with repository lint rules (#846)
EcstaceeLOR Oct 18, 2026
0596704
ci(test): collect independent gate results without masking any failure
EcstaceeLOR Oct 18, 2026
38c6d4b
docs(changelog): record corrected canonical brand and repository link…
EcstaceeLOR Oct 18, 2026
d34084a
chore: remove temporary CI verification workflow before upstream cont…
EcstaceeLOR Oct 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changelog/unreleased/9996-canonical-so4-brand-and-links.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
type: fixed
area: trade
pr: 9996
breaking: false
---

Site metadata, community links, and changelog and gallery GitHub URLs now consistently point to SO4 Market and its source repository.
4 changes: 2 additions & 2 deletions apps/web/public/manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"short_name": "Levee",
"name": "Levee — On-chain perpetuals",
"short_name": "SO4",
"name": "SO4 Market — On-chain perpetuals",
"description": "A unified-liquidity perp DEX. Deep books, sub-second matching, and self-custodied risk.",
"icons": [
{
Expand Down
2 changes: 1 addition & 1 deletion apps/web/public/og-image.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Badge } from "@workspace/ui/components/badge"
import { areaLabel, typeLabel, typeToVariant } from "../utils"
import { InlineMarkdown } from "./InlineMarkdown"
import type { ChangelogEntry as IChangelogEntry } from "../types"
import { REPO_URL } from "@/shared/lib/site-identity"

interface ChangelogEntryProps {
entry: IChangelogEntry
Expand Down Expand Up @@ -39,7 +40,7 @@ export function ChangelogEntry({ entry, highlight }: ChangelogEntryProps) {
{entry.pr && (
<div className="mt-2 sm:mt-0 sm:ml-4 shrink-0">
<a
href={`https://github.com/Levee-HQ/interface/pull/${entry.pr}`}
href={`${REPO_URL}/pull/${entry.pr}`}
target="_blank"
rel="noopener noreferrer"
className="inline-flex h-11 min-w-11 items-center justify-center px-3 text-xs/relaxed font-medium text-info transition-colors hover:text-info/80"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Icon } from "@workspace/ui/components/icon"
import { createAnchor, formatDate } from "../utils"
import { ChangelogEntry } from "./ChangelogEntry"
import type { Release } from "../types"
import { SITE_URL } from "@/shared/lib/site-identity"

interface ReleaseSectionProps {
release: Release
Expand All @@ -25,7 +26,7 @@ export function ReleaseSection({
const handleCopyPermalink = async () => {
const origin =
typeof window === "undefined"
? "https://so4.market"
? SITE_URL
: window.location.origin
const permalink = `${origin}/changelog${anchor}`
try {
Expand Down
5 changes: 3 additions & 2 deletions apps/web/src/features/gallery/components/gallery-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import type { ProgressIndicatorProps } from "@workspace/ui/components/progress-i
import { useDirection } from "@/ui/direction-provider"
import { ChangelogCategoryBadge } from "@/features/changelog/components/ChangelogCategoryBadge"
import { CHANGELOG_ENTRY_TYPES } from "@/features/changelog/types"
import { REPO_URL } from "@/shared/lib/site-identity"

const BUTTON_VARIANTS = [
"default",
Expand Down Expand Up @@ -105,14 +106,14 @@ export function GalleryPage() {
<p className="mt-1 text-sm text-muted-foreground">
Every packages/ui primitive, all variants. See{" "}
<a
href="https://github.com/Levee-HQ/interface/blob/main/DESIGN.md"
href={`${REPO_URL}/blob/main/DESIGN.md`}
className="text-primary underline underline-offset-2"
>
DESIGN.md
</a>{" "}
and{" "}
<a
href="https://github.com/Levee-HQ/interface/blob/main/packages/ui/CONTRIBUTING.md"
href={`${REPO_URL}/blob/main/packages/ui/CONTRIBUTING.md`}
className="text-primary underline underline-offset-2"
>
packages/ui/CONTRIBUTING.md
Expand Down
3 changes: 2 additions & 1 deletion apps/web/src/features/wallet/components/ConnectButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import type { ComponentProps } from "react"
import { useKeyboardShortcut } from "@/shared/hooks/useKeyboardShortcut"
import { useWallet } from "@/app/providers"
import { NETWORK } from "@/app/config/network"
import { SITE_URL } from "@/shared/lib/site-identity"

type ConnectButtonProps = Omit<
ComponentProps<typeof Button>,
Expand Down Expand Up @@ -278,7 +279,7 @@ function WalletModal({
)
const sep7Uri = useMemo(() => {
const origin =
typeof window === "undefined" ? "https://so4.market" : window.location.origin
typeof window === "undefined" ? SITE_URL : window.location.origin
const callbackUrl = new URL("/", origin).toString()

if (pendingTransactionXdr) {
Expand Down
22 changes: 10 additions & 12 deletions apps/web/src/routes/__root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@ import { TooltipProvider } from "@workspace/ui/components/tooltip"
import { DensityProvider } from "@workspace/ui/components/density-provider"
import appCss from "@workspace/ui/globals.css?url"
import { AppProviders } from "../app/providers"
import { SITE_NAME, SITE_URL, SOCIAL_URLS } from "../shared/lib/site-identity"
import { RouteAnnouncer } from "../shared/components/RouteAnnouncer"

// Update this to your production domain before going live.
const SITE_URL = "https://levee.market"
const SITE_NAME = "levee.market"
const TITLE = "Levee · On-chain perpetuals"
const TITLE = `${SITE_NAME} · On-chain perpetuals`
const DESCRIPTION =
"A unified-liquidity perp DEX. Deep books, sub-second matching, and self-custodied risk — built for traders who care where their fills come from."
// TODO(GF3-003): apply the dot-separator convention (no em dashes as list
Expand All @@ -34,7 +32,7 @@ const JSON_LD = {
{
"@type": "WebApplication",
"@id": `${SITE_URL}/#app`,
name: "Levee",
name: SITE_NAME,
url: SITE_URL,
description: DESCRIPTION,
applicationCategory: "FinanceApplication",
Expand All @@ -48,13 +46,13 @@ const JSON_LD = {
{
"@type": "Organization",
"@id": `${SITE_URL}/#org`,
name: "Levee Labs",
name: "SO4 Markets",
url: SITE_URL,
logo: `${SITE_URL}/favicon.svg`,
sameAs: [
"https://twitter.com/so4market",
"https://discord.gg/so4market",
"https://t.me/so4market",
SOCIAL_URLS.x,
SOCIAL_URLS.discord,
SOCIAL_URLS.telegram,
],
},
{
Expand All @@ -81,7 +79,7 @@ export const Route = createRootRoute({
content:
"perpetual DEX, on-chain perps, crypto derivatives, DeFi trading, BTC perp, ETH perp, low fee perp, self-custodied trading, unified liquidity",
},
{ name: "author", content: "Levee Labs" },
{ name: "author", content: "SO4 Markets" },
{ name: "robots", content: "index, follow, max-image-preview:large" },
// ds-allow: <meta content> requires a literal color string for
// mobile browser chrome tinting — can't reference a CSS custom
Expand All @@ -105,7 +103,7 @@ export const Route = createRootRoute({
{
property: "og:image:alt",
content:
"Levee · On-chain perpetuals DEX · unified liquidity for modern markets",
`${SITE_NAME} · On-chain perpetuals DEX · unified liquidity for modern markets`,
},

// ── Twitter / X Card ────────────────────────────────────────
Expand All @@ -118,7 +116,7 @@ export const Route = createRootRoute({
{
name: "twitter:image:alt",
content:
"Levee · On-chain perpetuals DEX · unified liquidity for modern markets",
`${SITE_NAME} · On-chain perpetuals DEX · unified liquidity for modern markets`,
},
],
links: [
Expand Down
35 changes: 35 additions & 0 deletions apps/web/src/shared/lib/site-identity.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { readFileSync } from "node:fs"
import { describe, expect, it } from "vitest"
import { DOCS_URL, REPO_URL, SITE_NAME, SITE_URL, SOCIAL_URLS } from "./site-identity"

describe("canonical product identity (#846)", () => {
it("uses the documented SO4 website, repository, and community channels", () => {
expect(SITE_NAME).toBe("SO4 Market")
expect(SITE_URL).toBe("https://so4.market")
expect(REPO_URL).toBe("https://github.com/SO4-Markets/interface")
expect(DOCS_URL).toBe("https://docs.so4.market")
expect(SOCIAL_URLS).toMatchObject({
github: REPO_URL,
x: "https://twitter.com/so4market",
discord: "https://discord.gg/so4market",
telegram: "https://t.me/so4market",
})
})

it("does not keep the competing domain or repository links in runtime sources", () => {
const files = [
"../../routes/__root.tsx",
"../../ui/landing/roadmap-section.tsx",
"../../ui/landing/social-section.tsx",
"../../features/changelog/components/ChangelogEntry.tsx",
"../../features/gallery/components/gallery-page.tsx",
"../../../public/og-image.svg",
"../../../public/manifest.json",
]

for (const path of files) {
const source = readFileSync(new URL(path, import.meta.url), "utf8")
expect(source, path).not.toMatch(/Levee-HQ|levee\.market/)
}
})
})
12 changes: 12 additions & 0 deletions apps/web/src/shared/lib/site-identity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Canonical destinations for web metadata, product links, and community links.
// Product name/domain pending confirmation in SO4-Markets/interface#846.
export const SITE_NAME = "SO4 Market"
export const SITE_URL = "https://so4.market"
export const REPO_URL = "https://github.com/SO4-Markets/interface"
export const DOCS_URL = "https://docs.so4.market"
export const SOCIAL_URLS = {
x: "https://twitter.com/so4market",
discord: "https://discord.gg/so4market",
telegram: "https://t.me/so4market",
github: REPO_URL,
} as const
3 changes: 2 additions & 1 deletion apps/web/src/ui/landing/faq-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import {
} from "@workspace/ui/components/accordion"

import { LANDING_FAQS } from "./faq.generated"
import { DOCS_URL } from "@/shared/lib/site-identity"

const DOCS_ORIGIN = "https://docs.so4.market"
const DOCS_ORIGIN = DOCS_URL

export function FaqSection() {
return (
Expand Down
5 changes: 3 additions & 2 deletions apps/web/src/ui/landing/roadmap-section.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Quarter } from "./quarter"
import type { QuarterData } from "./quarter"
import { REPO_URL } from "@/shared/lib/site-identity"

// No dated roadmap exists in the repo — GMX's quarter labels (Q1..Q4) imply
// specific committed dates, which would be a fabricated public promise if
Expand Down Expand Up @@ -48,7 +49,7 @@ export function RoadmapSection() {
{/* No dev-plan writeup exists yet — links to the source repo,
a real destination, rather than a dead "#" anchor. */}
<a
href="https://github.com/Levee-HQ/interface"
href={REPO_URL}
target="_blank"
rel="noreferrer"
className="btn-landing hidden shrink-0 rounded-8 px-4 py-2.5 text-14 sm:inline-flex"
Expand All @@ -74,7 +75,7 @@ export function RoadmapSection() {
</div>

<a
href="https://github.com/Levee-HQ/interface"
href={REPO_URL}
target="_blank"
rel="noreferrer"
className="btn-landing mt-6 flex w-full items-center justify-center rounded-8 px-4 py-2.5 text-14 sm:hidden"
Expand Down
9 changes: 5 additions & 4 deletions apps/web/src/ui/landing/social-section.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { NewsletterForm } from "./newsletter-form"
import { SocialSlider } from "./social-slider"
import { SOCIAL_URLS } from "@/shared/lib/site-identity"

// Counts stay "-" — no social account has a real follower count to report
// yet, and a fabricated number is worse than an honest placeholder. URLs
Expand All @@ -8,10 +9,10 @@ import { SocialSlider } from "./social-slider"
// the page is internally consistent; GitHub is the one link that's
// definitely real (this repo).
const SOCIAL_STATS = [
{ name: "Discord", value: "-", href: "https://discord.gg/so4market" },
{ name: "X", value: "-", href: "https://twitter.com/so4market" },
{ name: "Telegram", value: "-", href: "https://t.me/so4market" },
{ name: "GitHub", value: "Join", href: "https://github.com/Levee-HQ/interface" },
{ name: "Discord", value: "-", href: SOCIAL_URLS.discord },
{ name: "X", value: "-", href: SOCIAL_URLS.x },
{ name: "Telegram", value: "-", href: SOCIAL_URLS.telegram },
{ name: "GitHub", value: "Join", href: SOCIAL_URLS.github },
]

// GMX's referral-terms/media-kit/terms pages don't exist for SO4 yet — no
Expand Down