From d8d3877bfc25044273f16782402e9fb71529d6ab Mon Sep 17 00:00:00 2001 From: zhujingyang <72259332+zjy365@users.noreply.github.com> Date: Thu, 2 Nov 2023 14:03:20 +0800 Subject: [PATCH] feat:docs language-differentiated domain names (#4226) --- docs/4.0/code.json | 3 + docs/website/docusaurus.config.js | 5 + .../docusaurus-theme-classic/navbar.json | 6 +- docs/website/src/hooks/useWindow.ts | 51 +++++---- .../src/pages/components/Banner/index.tsx | 10 +- .../src/pages/components/Capability/index.tsx | 107 ++++++++---------- .../src/pages/components/Header/index.tsx | 20 ++-- .../components/Introduce/index.phone.scss | 4 +- .../src/pages/components/Introduce/index.scss | 2 +- .../src/pages/components/Introduce/index.tsx | 58 +++++----- docs/website/src/pages/index.tsx | 33 ++++-- .../src/pages/pricing/header/index.tsx | 12 +- docs/website/src/pages/pricing/index.tsx | 27 +++-- docs/website/src/pages/pricing/plan/index.tsx | 10 +- 14 files changed, 178 insertions(+), 170 deletions(-) diff --git a/docs/4.0/code.json b/docs/4.0/code.json index 584602c0999..942ced85478 100644 --- a/docs/4.0/code.json +++ b/docs/4.0/code.json @@ -636,5 +636,8 @@ }, "A cloud operating system based on the Kubernetes kernel": { "message": "以 Kubernetes 为内核的云操作系统" + }, + "Explore": { + "message": "了解更多" } } \ No newline at end of file diff --git a/docs/website/docusaurus.config.js b/docs/website/docusaurus.config.js index f93bc7d6bdf..cfb7b193682 100644 --- a/docs/website/docusaurus.config.js +++ b/docs/website/docusaurus.config.js @@ -102,6 +102,11 @@ const config = { to: "https://cloud.sealos.io", label: "Start Now" }, + { + position: "left", + to: "/pricing", + label: "Pricing" + }, { position: "left", to: "https://fael3z0zfze.feishu.cn/share/base/form/shrcnesSfEK65JZaAf2W6Fwz6Ad", diff --git a/docs/website/i18n/zh-Hans/docusaurus-theme-classic/navbar.json b/docs/website/i18n/zh-Hans/docusaurus-theme-classic/navbar.json index fd6cb70f27d..a7bb7fd772f 100644 --- a/docs/website/i18n/zh-Hans/docusaurus-theme-classic/navbar.json +++ b/docs/website/i18n/zh-Hans/docusaurus-theme-classic/navbar.json @@ -7,6 +7,10 @@ "message": "商务合作", "description": "Navbar item with label Contact" }, + "item.label.Pricing": { + "message": "价格", + "description": "Navbar item with label Contact" + }, "logo.alt": { "message": "sealos", "description": "The alt text of navbar logo" @@ -15,4 +19,4 @@ "message": "在线使用", "description": "Navbar item with label Start Now" } -} +} \ No newline at end of file diff --git a/docs/website/src/hooks/useWindow.ts b/docs/website/src/hooks/useWindow.ts index 250dc148c6f..a96a7c5d05b 100644 --- a/docs/website/src/hooks/useWindow.ts +++ b/docs/website/src/hooks/useWindow.ts @@ -1,24 +1,37 @@ -import { useEffect, useState } from "react"; +import { useEffect, useState } from 'react'; import useIsBrowser from '@docusaurus/useIsBrowser'; -export default function() { - const isBrowser = useIsBrowser(); - const [screenWidth, setScreenWidth] = useState(isBrowser ? document.body.clientWidth : 1440) +export default function () { + const isBrowser = useIsBrowser(); + const [screenWidth, setScreenWidth] = useState(isBrowser ? document.body.clientWidth : 1440); + const [currentLanguage, setCurrentLanguage] = useState( + isBrowser ? document.documentElement.lang : 'en' + ); + const [cloudUrl, setCloudUrl] = useState('https://cloud.sealos.io'); - useEffect(() => { - if(!isBrowser) return - setScreenWidth(document.body.clientWidth) - const updateScreenWidth = () => { - requestAnimationFrame(() => setScreenWidth(document?.body.clientWidth)) - } - window.addEventListener('resize', updateScreenWidth) + useEffect(() => { + if (!isBrowser) return; + setScreenWidth(document.body.clientWidth); + const updateScreenWidth = () => { + requestAnimationFrame(() => setScreenWidth(document?.body.clientWidth)); + }; + window.addEventListener('resize', updateScreenWidth); + // handle + setCurrentLanguage(document.documentElement.lang); + setCloudUrl( + document.documentElement.lang === 'en' + ? 'https://cloud.sealos.io' + : 'https://cloud.sealos.top' + ); - return () => { - window.removeEventListener('resize', updateScreenWidth) - } - },[isBrowser]) + return () => { + window.removeEventListener('resize', updateScreenWidth); + }; + }, [isBrowser]); - return { - screenWidth - } -} \ No newline at end of file + return { + screenWidth, + currentLanguage, + cloudUrl + }; +} diff --git a/docs/website/src/pages/components/Banner/index.tsx b/docs/website/src/pages/components/Banner/index.tsx index 67de416fd69..85656a6f64d 100644 --- a/docs/website/src/pages/components/Banner/index.tsx +++ b/docs/website/src/pages/components/Banner/index.tsx @@ -3,10 +3,11 @@ import DrawIcon from '@site/static/icons/draw.svg'; import LogoIcon from '@site/static/icons/sealos.svg'; import React, { useEffect, useState } from 'react'; import './index.scss'; +import useWindow from '@site/src/hooks/useWindow'; export default function Banner() { const [isBannerVisible, setIsBannerVisible] = useState(false); - const [doMain, setDoMain] = useState(''); + const { screenWidth, currentLanguage, cloudUrl } = useWindow(); const closeBanner = () => { setIsBannerVisible(false); @@ -17,8 +18,6 @@ export default function Banner() { }; useEffect(() => { - let url = window.self === window.top ? 'cloud.sealos.io' : 'cloud.sealos.top'; - setDoMain(url); // Get the last display timestamp from localStorage const lastDisplayTimestamp = localStorage.getItem('bannerLastDisplay'); const today = new Date().toLocaleDateString(); @@ -65,10 +64,7 @@ export default function Banner() {
{ - window.open( - `https://${doMain}/?openapp=system-costcenter?openRecharge=true`, - '_blank' - ); + window.open(`${cloudUrl}/?openapp=system-costcenter?openRecharge=true`, '_blank'); closeBanner(); }} > diff --git a/docs/website/src/pages/components/Capability/index.tsx b/docs/website/src/pages/components/Capability/index.tsx index 22d9a8e1ec7..14c54f71c72 100644 --- a/docs/website/src/pages/components/Capability/index.tsx +++ b/docs/website/src/pages/components/Capability/index.tsx @@ -1,39 +1,42 @@ -import React, { useLayoutEffect } from 'react' -import CometIcon from '../Comet' -import ApplaunchpadIcon from '@site/static/icons/applaunchpad.svg' -import ServerlessIcon from '@site/static/icons/serverless.svg' -import DataBaseIcon from '@site/static/icons/database.svg' -import useIsBrowser from '@docusaurus/useIsBrowser' -import './index.scss' -import Translate from '@docusaurus/Translate' +import Translate from '@docusaurus/Translate'; +import useIsBrowser from '@docusaurus/useIsBrowser'; +import useWindow from '@site/src/hooks/useWindow'; +import ApplaunchpadIcon from '@site/static/icons/applaunchpad.svg'; +import DataBaseIcon from '@site/static/icons/database.svg'; +import ServerlessIcon from '@site/static/icons/serverless.svg'; +import React, { useLayoutEffect } from 'react'; +import CometIcon from '../Comet'; +import './index.scss'; const i18nObj = { capability: The Capabilities of Sealos, appMan: Application Management, appManagement_introduce: ( - Rapidly deploy any distributed application with the ability to access the - public network. + Easy management and quick release of publicly accessible distributed applications in the app + store. ), database: Database, database_introduce: ( - Create highly available databases in seconds that support MySQL, - PostgreSQL, MongoDB, and Redis. + Create high-availability databases in seconds, offering support for MySQL, PostgreSQL, + MongoDB, and Redis. ), - serverless: Serverless, + serverless: Cloud Universality, serverless_introduce: ( - Serverless computing makes writing code as easy as blogging, allowing you - to launch and deploy your business code anytime, anywhere. + Equally effective in both public and private cloud, enabling a seamless transition of + traditional applications to the cloud. ), -} + Explore: Explore +}; const Capability = ({ isPc }: { isPc: boolean }) => { - const isBrowser = useIsBrowser() + const isBrowser = useIsBrowser(); + const { screenWidth, currentLanguage, cloudUrl } = useWindow(); useLayoutEffect(() => { // @ts-ignore nextline @@ -44,10 +47,10 @@ const Capability = ({ isPc }: { isPc: boolean }) => { animateClass: 'animate__fadeIn', offset: 0, mobile: false, - live: false, - }).init() + live: false + }).init(); } - }, [isBrowser]) + }, [isBrowser]); if (!isPc) { return ( @@ -63,19 +66,14 @@ const Capability = ({ isPc }: { isPc: boolean }) => {

{i18nObj.appMan}

{i18nObj.appManagement_introduce}

- - Explore {'>'} + + {i18nObj.Explore} {'>'} app-management @@ -86,18 +84,13 @@ const Capability = ({ isPc }: { isPc: boolean }) => {
{i18nObj.database}
{i18nObj.database_introduce}
- - Explore {'>'} + + {i18nObj.Explore} {'>'} app-management @@ -110,13 +103,13 @@ const Capability = ({ isPc }: { isPc: boolean }) => {
{i18nObj.serverless_introduce}
- Explore {'>'} + href={currentLanguage === 'en' ? '/pricing' : '/zh-Hans/pricing'} + > + {i18nObj.Explore} {'>'} - ) + ); } return ( @@ -132,19 +125,14 @@ const Capability = ({ isPc }: { isPc: boolean }) => {

{i18nObj.appMan}

{i18nObj.appManagement_introduce}

- - Explore {'>'} + + {i18nObj.Explore} {'>'} app-management @@ -155,18 +143,13 @@ const Capability = ({ isPc }: { isPc: boolean }) => {
{i18nObj.database}
{i18nObj.database_introduce}
- - Explore {'>'} + + {i18nObj.Explore} {'>'} app-management @@ -178,14 +161,14 @@ const Capability = ({ isPc }: { isPc: boolean }) => {
{i18nObj.serverless_introduce}
- Explore {'>'} + href={currentLanguage === 'en' ? '/pricing' : '/zh-Hans/pricing'} + > + {i18nObj.Explore} {'>'} - ) -} + ); +}; -export default React.memo(Capability) +export default React.memo(Capability); diff --git a/docs/website/src/pages/components/Header/index.tsx b/docs/website/src/pages/components/Header/index.tsx index 5e4b5ce2bff..1d4bf4d8f78 100644 --- a/docs/website/src/pages/components/Header/index.tsx +++ b/docs/website/src/pages/components/Header/index.tsx @@ -1,14 +1,15 @@ import Link from '@docusaurus/Link'; import Translate from '@docusaurus/Translate'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import useIsBrowser from '@docusaurus/useIsBrowser'; +import useWindow from '@site/src/hooks/useWindow'; import GithubIcon from '@site/static/icons/github.svg'; import MeunIcon from '@site/static/icons/meun.svg'; import LogoIcon from '@site/static/icons/sealos.svg'; -import React, { useEffect, useMemo, useState } from 'react'; +import HeaderSvg from '@site/static/illustrations/bg-header.svg'; +import React, { useEffect, useState } from 'react'; import VideoPlayer from '../VideoPlayer'; import './index.scss'; -import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import useIsBrowser from '@docusaurus/useIsBrowser'; -import HeaderSvg from '@site/static/illustrations/bg-header.svg'; const navbar = [ { @@ -41,14 +42,7 @@ const i18nObj = { const HomeHeader = ({ isPc }: { isPc: boolean }) => { const [stars, setStars] = useState(10000); const isBrowser = useIsBrowser(); - const [cloudUrl, setCloudurl] = useState('https://cloud.sealos.io'); - useEffect(() => { - if (!!window) { - setCloudurl( - window.self === window.top ? 'https://cloud.sealos.io' : 'https://cloud.sealos.top' - ); - } - }, []); + const { cloudUrl } = useWindow(); const i18nMap: { [key: string]: { label: string; link: string } } = { en: { label: '中', link: '/zh-Hans/' }, @@ -60,7 +54,7 @@ const HomeHeader = ({ isPc }: { isPc: boolean }) => { siteConfig: { themeConfig: { // @ts-ignore nextLine - navbar: { items: navbarData } + // navbar: { items: navbarData } } } } = useDocusaurusContext(); diff --git a/docs/website/src/pages/components/Introduce/index.phone.scss b/docs/website/src/pages/components/Introduce/index.phone.scss index 82417b181d7..6c0e8057c3b 100644 --- a/docs/website/src/pages/components/Introduce/index.phone.scss +++ b/docs/website/src/pages/components/Introduce/index.phone.scss @@ -113,13 +113,13 @@ } .tag2 { @extend .tag; - margin-top: 74px; + margin-top: 90px; width: fit-content; color: #8fe3de; } .tag3 { @extend .tag; - margin-top: 44px; + margin-top: 80px; color: #aa9fec; } diff --git a/docs/website/src/pages/components/Introduce/index.scss b/docs/website/src/pages/components/Introduce/index.scss index fdaa54d7989..ec034df4c60 100644 --- a/docs/website/src/pages/components/Introduce/index.scss +++ b/docs/website/src/pages/components/Introduce/index.scss @@ -52,7 +52,7 @@ } .tag3 { @extend .tag; - margin-top: 300px; + margin-top: 310px; color: #aa9fec; } diff --git a/docs/website/src/pages/components/Introduce/index.tsx b/docs/website/src/pages/components/Introduce/index.tsx index 2b30dc06e84..4be25aa7c3b 100644 --- a/docs/website/src/pages/components/Introduce/index.tsx +++ b/docs/website/src/pages/components/Introduce/index.tsx @@ -1,37 +1,37 @@ -import React, { useLayoutEffect } from 'react' -import CometIcon from '../Comet' -import RouteIcon from '@site/static/icons/route-icon.svg' -import useIsBrowser from '@docusaurus/useIsBrowser' -import './index.scss' -import Translate from '@docusaurus/Translate' +import React, { useLayoutEffect } from 'react'; +import CometIcon from '../Comet'; +import RouteIcon from '@site/static/icons/route-icon.svg'; +import useIsBrowser from '@docusaurus/useIsBrowser'; +import './index.scss'; +import Translate from '@docusaurus/Translate'; const Introduce = ({ isPc }: { isPc: boolean }) => { - const isBrowser = useIsBrowser() + const isBrowser = useIsBrowser(); const i18nObj = { whySealos: Why Sealos, - lowerCosts: Lower Costs, + lowerCosts: Efficient & Economical, lowerCostsIntroduce: ( - Save resources and reduce expenses by paying only for containers, with - automatic scaling to prevent waste. + Pay solely for the containers you utilize; automatic scaling prevents resource squandering + and substantially reduces costs. ), userFriendly: User Friendly, userFriendlyIntroduce: ( - Focus on your business without being bogged down by unnecessary - complexity, regardless of your level of Kubernetes expertise. + Concentrate on your core business activities without worrying about system complexities; + negligible learning costs involved. ), - flexibilitySecurity: Flexibility and Security, + flexibilitySecurity: Agility & Security, flexibilitySecurityIntroduce: ( - Its unique multi-tenant sharing mechanism can achieve effective resource - isolation and collaboration while ensuring safety. + The distinctive multi-tenancy sharing model ensures both effective resource segmentation and + collaboration, all under a secure framework. - ), - } + ) + }; useLayoutEffect(() => { // @ts-ignore nextline @@ -42,10 +42,10 @@ const Introduce = ({ isPc }: { isPc: boolean }) => { animateClass: 'animate__fadeIn', offset: 0, mobile: true, - live: false, - }).init() + live: false + }).init(); } - }, [isBrowser]) + }, [isBrowser]); if (!isPc) { return ( @@ -74,7 +74,8 @@ const Introduce = ({ isPc }: { isPc: boolean }) => { width="20" height="19" viewBox="0 0 20 19" - fill="none"> + fill="none" + > @@ -87,13 +88,11 @@ const Introduce = ({ isPc }: { isPc: boolean }) => {
{i18nObj.userFriendlyIntroduce}
{i18nObj.flexibilitySecurity}
-
- {i18nObj.flexibilitySecurityIntroduce} -
+
{i18nObj.flexibilitySecurityIntroduce}
- ) + ); } return ( @@ -130,7 +129,8 @@ const Introduce = ({ isPc }: { isPc: boolean }) => { width="20" height="19" viewBox="0 0 20 19" - fill="none"> + fill="none" + > @@ -141,7 +141,7 @@ const Introduce = ({ isPc }: { isPc: boolean }) => { - ) -} + ); +}; -export default React.memo(Introduce) +export default React.memo(Introduce); diff --git a/docs/website/src/pages/index.tsx b/docs/website/src/pages/index.tsx index 51f973349ef..c32f40278bf 100644 --- a/docs/website/src/pages/index.tsx +++ b/docs/website/src/pages/index.tsx @@ -1,22 +1,42 @@ import '@site/src/css/animate.css'; import Layout from '@theme/Layout'; -import React, { useMemo } from 'react'; +import React, { useEffect, useMemo } from 'react'; +import { Helmet } from 'react-helmet'; import { PC_MIN_WIDTH } from '../constants/platform'; import useWindow from '../hooks/useWindow'; +import Banner from './components/Banner'; import Capability from './components/Capability'; import Community from './components/Community'; import HomeFooter from './components/Footer'; import HomeHeader from './components/Header'; import Introduce from './components/Introduce'; import HomeUserBy from './components/UserBy'; -import { Helmet } from 'react-helmet'; import './index.scss'; -import Banner from './components/Banner'; const Home = () => { - const { screenWidth } = useWindow(); + const { screenWidth, currentLanguage, cloudUrl } = useWindow(); const isPc = useMemo(() => screenWidth > PC_MIN_WIDTH, [screenWidth]); + useEffect(() => { + const loadUmamiScript = () => { + const hostname = window.location.hostname; + if (hostname === 'sealos.run') { + const script1 = document.createElement('script'); + script1.src = 'https://umami.cloud.sealos.io/oishii'; + script1.setAttribute('data-website-id', 'e5a8009f-7cb6-4841-9522-d23b96216b7a'); + script1.async = true; + document.head.appendChild(script1); + } else { + const script2 = document.createElement('script'); + script2.src = 'https://umami.cloud.sealos.io/oishii'; + script2.setAttribute('data-website-id', 'a1c29ace-b288-431a-a2eb-8617d1d5b5ed'); + script2.async = true; + document.head.appendChild(script2); + } + }; + loadUmamiScript(); + }, []); + const HomeRender = (
@@ -31,11 +51,6 @@ const Home = () => { gtag('event', 'conversion', {'send_to': 'AW-786053845/LpbTCJ-8-coYENX16PYC'}); `} -
diff --git a/docs/website/src/pages/pricing/header/index.tsx b/docs/website/src/pages/pricing/header/index.tsx index af0df47ec37..5cee27c75b5 100644 --- a/docs/website/src/pages/pricing/header/index.tsx +++ b/docs/website/src/pages/pricing/header/index.tsx @@ -7,6 +7,7 @@ import MeunIcon from '@site/static/icons/meun.svg'; import LogoIcon from '@site/static/icons/sealos.svg'; import React, { useEffect, useMemo, useState } from 'react'; import './index.scss'; +import useWindow from '@site/src/hooks/useWindow'; const navbar = [ { @@ -39,14 +40,7 @@ const i18nObj = { const HomeHeader = ({ isPc }: { isPc: boolean }) => { const [stars, setStars] = useState(10000); const isBrowser = useIsBrowser(); - const [cloudUrl, setCloudurl] = useState('https://cloud.sealos.io'); - useEffect(() => { - if (!!window) { - setCloudurl( - window.self === window.top ? 'https://cloud.sealos.io' : 'https://cloud.sealos.top' - ); - } - }, []); + const { screenWidth, currentLanguage, cloudUrl } = useWindow(); const i18nMap: { [key: string]: { label: string; link: string } } = { en: { label: '中', link: '/zh-Hans/' }, @@ -58,7 +52,7 @@ const HomeHeader = ({ isPc }: { isPc: boolean }) => { siteConfig: { themeConfig: { // @ts-ignore nextLine - navbar: { items: navbarData } + // navbar: { items: navbarData } } } } = useDocusaurusContext(); diff --git a/docs/website/src/pages/pricing/index.tsx b/docs/website/src/pages/pricing/index.tsx index 7c649b6d5cb..e7c54daf79f 100644 --- a/docs/website/src/pages/pricing/index.tsx +++ b/docs/website/src/pages/pricing/index.tsx @@ -9,23 +9,28 @@ import Plan from './plan'; import Product from './product'; import Advantage from './advantage'; import Overview from './overview'; +import Layout from '@theme/Layout'; export default function Pricing() { const { screenWidth } = useWindow(); const isPc = useMemo(() => screenWidth > PC_MIN_WIDTH, [screenWidth]); return ( -
-
- -
-
-
- - - - -