From 919ae0bc37da7b59c7bb15e79e4b96546794e5e4 Mon Sep 17 00:00:00 2001 From: Face <69168154+face-hh@users.noreply.github.com> Date: Fri, 30 May 2025 13:15:00 +0300 Subject: [PATCH] feat: SEO --- website/src/app.html | 15 ++++ website/src/lib/components/self/SEO.svelte | 81 +++++++++++++++++++ website/src/routes/+page.svelte | 7 ++ .../src/routes/coin/[coinSymbol]/+page.svelte | 17 +++- website/src/routes/coin/create/+page.svelte | 9 ++- website/src/routes/gambling/+page.svelte | 11 ++- website/src/routes/hopium/+page.svelte | 16 ++-- website/src/routes/hopium/[id]/+page.svelte | 26 +++--- website/src/routes/leaderboard/+page.svelte | 15 ++-- website/src/routes/legal/privacy/+page.svelte | 25 ++---- website/src/routes/legal/terms/+page.svelte | 8 +- website/src/routes/live/+page.svelte | 7 ++ website/src/routes/market/+page.svelte | 24 ++---- website/src/routes/portfolio/+page.svelte | 10 ++- website/src/routes/settings/+page.svelte | 8 ++ website/src/routes/treemap/+page.svelte | 10 ++- .../src/routes/user/[username]/+page.svelte | 28 ++++--- 17 files changed, 226 insertions(+), 91 deletions(-) create mode 100644 website/src/lib/components/self/SEO.svelte diff --git a/website/src/app.html b/website/src/app.html index 77a5ff5..5ff71ed 100644 --- a/website/src/app.html +++ b/website/src/app.html @@ -3,7 +3,22 @@ + + + Rugplay + + + + + + + + + + + + %sveltekit.head% diff --git a/website/src/lib/components/self/SEO.svelte b/website/src/lib/components/self/SEO.svelte new file mode 100644 index 0000000..d58573d --- /dev/null +++ b/website/src/lib/components/self/SEO.svelte @@ -0,0 +1,81 @@ + + + + + {title} + + + + + {#if noindex} + + {:else} + + {/if} + + + {#if canonical} + + {/if} + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/src/routes/+page.svelte b/website/src/routes/+page.svelte index dff987d..b787c9c 100644 --- a/website/src/routes/+page.svelte +++ b/website/src/routes/+page.svelte @@ -7,6 +7,7 @@ import CoinIcon from '$lib/components/self/CoinIcon.svelte'; import DataTable from '$lib/components/self/DataTable.svelte'; import HomeSkeleton from '$lib/components/self/skeletons/HomeSkeleton.svelte'; + import SEO from '$lib/components/self/SEO.svelte'; import { onMount } from 'svelte'; import { toast } from 'svelte-sonner'; import { goto } from '$app/navigation'; @@ -76,6 +77,12 @@ ]; + +
diff --git a/website/src/routes/coin/[coinSymbol]/+page.svelte b/website/src/routes/coin/[coinSymbol]/+page.svelte index 5340f80..8cd4e1a 100644 --- a/website/src/routes/coin/[coinSymbol]/+page.svelte +++ b/website/src/routes/coin/[coinSymbol]/+page.svelte @@ -25,6 +25,7 @@ import { fetchPortfolioData } from '$lib/stores/portfolio-data'; import { getPublicUrl, getTimeframeInSeconds } from '$lib/utils.js'; import { websocketController, type PriceUpdate, isConnectedStore } from '$lib/stores/websocket'; + import SEO from '$lib/components/self/SEO.svelte'; const { data } = $props(); const coinSymbol = data.coinSymbol; @@ -329,9 +330,19 @@ } - - {coin ? `${coin.name} (${coin.symbol})` : 'Loading...'} - Rugplay - += 0 ? '+' : ''}${coin.change24h.toFixed(2)}%.` + : `Virtual cryptocurrency trading page for ${coinSymbol.toUpperCase()} in the Rugplay simulation game.`} + keywords={coin + ? `${coin.name} cryptocurrency game, *${coin.symbol} virtual trading, ${coin.symbol} price simulation, cryptocurrency trading game, virtual coin ${coin.symbol}` + : `${coinSymbol} virtual cryptocurrency, crypto trading simulation, virtual coin trading`} + image={coin?.icon ? getPublicUrl(coin.icon) : '/placeholder_logo.png'} + imageAlt={coin ? `${coin.name} (${coin.symbol}) logo` : `${coinSymbol} cryptocurrency logo`} +/> {#if coin} diff --git a/website/src/routes/coin/create/+page.svelte b/website/src/routes/coin/create/+page.svelte index 1095f67..cdf0d67 100644 --- a/website/src/routes/coin/create/+page.svelte +++ b/website/src/routes/coin/create/+page.svelte @@ -11,6 +11,7 @@ import { onMount } from 'svelte'; import { CREATION_FEE, INITIAL_LIQUIDITY, TOTAL_COST } from '$lib/data/constants'; import { toast } from 'svelte-sonner'; + import SEO from '$lib/components/self/SEO.svelte'; let name = $state(''); let symbol = $state(''); @@ -113,9 +114,11 @@ } - - Create Coin - Rugplay - +
diff --git a/website/src/routes/gambling/+page.svelte b/website/src/routes/gambling/+page.svelte index f1ba406..96183d1 100644 --- a/website/src/routes/gambling/+page.svelte +++ b/website/src/routes/gambling/+page.svelte @@ -7,6 +7,7 @@ import { toast } from 'svelte-sonner'; import SignInConfirmDialog from '$lib/components/self/SignInConfirmDialog.svelte'; import { Button } from '$lib/components/ui/button'; + import SEO from '$lib/components/self/SEO.svelte'; let shouldSignIn = $state(false); let balance = $state(0); @@ -36,11 +37,15 @@ }); + + - - Gambling - Rugplay - +

Gambling

diff --git a/website/src/routes/hopium/+page.svelte b/website/src/routes/hopium/+page.svelte index d673a78..38da00b 100644 --- a/website/src/routes/hopium/+page.svelte +++ b/website/src/routes/hopium/+page.svelte @@ -7,10 +7,10 @@ import { Input } from '$lib/components/ui/input'; import { Label } from '$lib/components/ui/label'; import { Badge } from '$lib/components/ui/badge'; - import { Skeleton } from '$lib/components/ui/skeleton'; import * as Avatar from '$lib/components/ui/avatar'; import UserProfilePreview from '$lib/components/self/UserProfilePreview.svelte'; import HopiumSkeleton from '$lib/components/self/skeletons/HopiumSkeleton.svelte'; + import SEO from '$lib/components/self/SEO.svelte'; import { TrendingUp, TrendingDown, @@ -19,8 +19,6 @@ Sparkles, Globe, Loader2, - CheckCircle, - XCircle, CheckIcon, XIcon } from 'lucide-svelte'; @@ -124,13 +122,11 @@ }); - - Hopium - Prediction Market | Rugplay - - + diff --git a/website/src/routes/hopium/[id]/+page.svelte b/website/src/routes/hopium/[id]/+page.svelte index 1152149..57a5227 100644 --- a/website/src/routes/hopium/[id]/+page.svelte +++ b/website/src/routes/hopium/[id]/+page.svelte @@ -9,6 +9,7 @@ import * as Avatar from '$lib/components/ui/avatar'; import { Separator } from '$lib/components/ui/separator'; import UserProfilePreview from '$lib/components/self/UserProfilePreview.svelte'; + import SEO from '$lib/components/self/SEO.svelte'; import { Loader2, Calculator, @@ -194,14 +195,15 @@ ); - - {#if question} - {question.question} - Rugplay - - {:else} - Hopium - Rugplay - {/if} - +
{#if loading} @@ -591,8 +593,12 @@ >
-
{bet.user?.name || "Deleted User"}
-
@{bet.user?.username || "deleted_user"}
+
+ {bet.user?.name || 'Deleted User'} +
+
+ @{bet.user?.username || 'deleted_user'} +
diff --git a/website/src/routes/leaderboard/+page.svelte b/website/src/routes/leaderboard/+page.svelte index 4b3013d..979e434 100644 --- a/website/src/routes/leaderboard/+page.svelte +++ b/website/src/routes/leaderboard/+page.svelte @@ -1,15 +1,14 @@ - - Leaderboard - Rugplay - +
diff --git a/website/src/routes/legal/privacy/+page.svelte b/website/src/routes/legal/privacy/+page.svelte index 43e79fb..9922b08 100644 --- a/website/src/routes/legal/privacy/+page.svelte +++ b/website/src/routes/legal/privacy/+page.svelte @@ -6,30 +6,17 @@ import ShieldCheck from 'lucide-svelte/icons/shield-check'; import AlertTriangle from 'lucide-svelte/icons/alert-triangle'; import { goto } from '$app/navigation'; - import { page } from '$app/state'; + import SEO from '$lib/components/self/SEO.svelte'; const LAST_UPDATED = 'May 29, 2025'; const CONTACT_EMAIL = 'privacy@outpoot.com'; - - Privacy Policy - Rugplay - - - - - - - +
diff --git a/website/src/routes/legal/terms/+page.svelte b/website/src/routes/legal/terms/+page.svelte index 056f687..6af532f 100644 --- a/website/src/routes/legal/terms/+page.svelte +++ b/website/src/routes/legal/terms/+page.svelte @@ -7,13 +7,19 @@ import AlertTriangle from 'lucide-svelte/icons/alert-triangle'; import TrendingDown from 'lucide-svelte/icons/trending-down'; import { goto } from '$app/navigation'; - import { page } from '$app/state'; + import SEO from '$lib/components/self/SEO.svelte'; const LAST_UPDATED = 'May 29, 2025'; const CONTACT_EMAIL = 'contact@outpoot.com'; const MINIMUM_AGE = 18; + +
diff --git a/website/src/routes/live/+page.svelte b/website/src/routes/live/+page.svelte index 4b3fe46..ad2b722 100644 --- a/website/src/routes/live/+page.svelte +++ b/website/src/routes/live/+page.svelte @@ -10,6 +10,7 @@ import CoinIcon from '$lib/components/self/CoinIcon.svelte'; import UserProfilePreview from '$lib/components/self/UserProfilePreview.svelte'; import LiveTradeSkeleton from '$lib/components/self/skeletons/LiveTradeSkeleton.svelte'; + import SEO from '$lib/components/self/SEO.svelte'; function handleUserClick(username: string) { goto(`/user/${username}`); @@ -20,6 +21,12 @@ } + + Live Trades - Rugplay diff --git a/website/src/routes/market/+page.svelte b/website/src/routes/market/+page.svelte index 65b9054..0d21a48 100644 --- a/website/src/routes/market/+page.svelte +++ b/website/src/routes/market/+page.svelte @@ -9,20 +9,12 @@ import { Label } from '$lib/components/ui/label'; import CoinIcon from '$lib/components/self/CoinIcon.svelte'; import MarketSkeleton from '$lib/components/self/skeletons/MarketSkeleton.svelte'; + import SEO from '$lib/components/self/SEO.svelte'; import { onMount } from 'svelte'; import { toast } from 'svelte-sonner'; import { goto } from '$app/navigation'; import { page } from '$app/stores'; - import { - Search, - RefreshCw, - SlidersHorizontal, - ChevronLeft, - ChevronRight, - DollarSign, - TrendingUp, - ArrowUpDown - } from 'lucide-svelte'; + import { Search, RefreshCw, SlidersHorizontal, ChevronLeft, ChevronRight } from 'lucide-svelte'; import { formatPrice, formatMarketCap, debounce, formatRelativeTime } from '$lib/utils'; import { MediaQuery } from 'svelte/reactivity'; import type { CoinData, FilterOption, VolatilityBadge, MarketResponse } from '$lib/types/market'; @@ -240,13 +232,11 @@ ); - - Market - Rugplay - - +
diff --git a/website/src/routes/portfolio/+page.svelte b/website/src/routes/portfolio/+page.svelte index 13a013e..9554747 100644 --- a/website/src/routes/portfolio/+page.svelte +++ b/website/src/routes/portfolio/+page.svelte @@ -5,6 +5,7 @@ import CoinIcon from '$lib/components/self/CoinIcon.svelte'; import DataTable from '$lib/components/self/DataTable.svelte'; import PortfolioSkeleton from '$lib/components/self/skeletons/PortfolioSkeleton.svelte'; + import SEO from '$lib/components/self/SEO.svelte'; import { getPublicUrl, formatPrice, formatValue, formatQuantity, formatDate } from '$lib/utils'; import { onMount } from 'svelte'; import { toast } from 'svelte-sonner'; @@ -161,9 +162,12 @@ ]); - - Portfolio - Rugplay - +
diff --git a/website/src/routes/settings/+page.svelte b/website/src/routes/settings/+page.svelte index f2bb1c0..605af10 100644 --- a/website/src/routes/settings/+page.svelte +++ b/website/src/routes/settings/+page.svelte @@ -15,6 +15,7 @@ import { volumeSettings } from '$lib/stores/volume-settings'; import { USER_DATA } from '$lib/stores/user-data'; import * as Dialog from '$lib/components/ui/dialog'; + import SEO from '$lib/components/self/SEO.svelte'; let name = $state($USER_DATA?.name || ''); let bio = $state($USER_DATA?.bio ?? ''); @@ -259,6 +260,13 @@ } + +

Settings

diff --git a/website/src/routes/treemap/+page.svelte b/website/src/routes/treemap/+page.svelte index 1c8a397..ccabf31 100644 --- a/website/src/routes/treemap/+page.svelte +++ b/website/src/routes/treemap/+page.svelte @@ -10,6 +10,7 @@ import { formatValue } from '$lib/utils'; import { allTradesStore } from '$lib/stores/websocket'; import { Button } from '$lib/components/ui/button'; + import SEO from '$lib/components/self/SEO.svelte'; interface CoinData { symbol: string; @@ -192,10 +193,11 @@ }); - - Treemap - Rugplay - - +
- - {profileData?.profile?.name - ? `${profileData.profile.name} (@${profileData.profile.username})` - : 'Loading...'} - Rugplay - - +
{#if loading}