[website] Add head, links and meta tags (#411)
* add assets * add head, links and meta tags * add url origin * rebase * update head * comment out placeholder og images * add scrollRestoration * fix related posts * rm browserconfig.xml * remove icons * u * u * lint * Update error-page.tsx * rm twitter meta
This commit is contained in:
parent
ceb1f60605
commit
9d2b3e9cea
|
@ -30,6 +30,7 @@ let config = {
|
|||
experimental: {
|
||||
legacyBrowsers: false,
|
||||
// esmExternals: 'loose',
|
||||
scrollRestoration: true,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
Binary file not shown.
Before Width: | Height: | Size: 6.0 KiB |
|
@ -1,53 +0,0 @@
|
|||
import Head from 'next/head'
|
||||
|
||||
type Props = {
|
||||
index?: boolean
|
||||
children?: React.ReactElement
|
||||
imageUrl?: string
|
||||
}
|
||||
|
||||
function _Head(props: Props) {
|
||||
const { index = true, children, imageUrl } = props
|
||||
return (
|
||||
<Head>
|
||||
<title>Status</title>
|
||||
<meta name="description" content="Generated by create next app" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
{/* todo: app stores banners/redirects */}
|
||||
{/* todo: eval following meta tags */}
|
||||
<meta property="og:site_name" content="Join Status" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content="Status — A secure messaging app, crypto wallet, and Web3 browser"
|
||||
/>
|
||||
<meta property="og:title" content="Join [@|#]<name> in Status" />
|
||||
<meta property="og:url" content="<url>" />
|
||||
|
||||
{imageUrl && <meta property="og:image" content={imageUrl} />}
|
||||
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:site" content="@ethstatus" />
|
||||
{/* <meta property="twitter:image" content="<logo>" /> */}
|
||||
<meta property="twitter:image:alt" content="Status logo" />
|
||||
<meta property="status-im:target" content="<displayName>" />
|
||||
<meta property="al:ios:url" content="status-im:/<url>" />
|
||||
<meta property="al:ios:app_store_id" content="1178893006" />
|
||||
<meta property="al:ios:app_name" content="Status — Ethereum. Anywhere" />
|
||||
<meta property="al:android:url" content="status-im:/<url>" />
|
||||
<meta property="al:android:package" content="im.status.ethereum" />
|
||||
<meta
|
||||
property="al:android:app_name"
|
||||
content="Status — Ethereum. Anywhere"
|
||||
/>
|
||||
{/* todo?: except communities; ask product */}
|
||||
{!index && <meta name="robots" content="noindex" />}
|
||||
{/* todo?: entity QR */}
|
||||
{/* todo?: fallback OG */}
|
||||
{children}
|
||||
</Head>
|
||||
)
|
||||
}
|
||||
|
||||
export { _Head as Head }
|
|
@ -2,6 +2,7 @@ import Image from 'next/image'
|
|||
import { useRouter } from 'next/router'
|
||||
import { match, P } from 'ts-pattern'
|
||||
|
||||
import logoBlogSrc from '../../public/images/logo/blog.svg'
|
||||
import logoSrc from '../../public/images/logo/default.svg'
|
||||
import logoDevSrc from '../../public/images/logo/dev.svg'
|
||||
import logoLearnSrc from '../../public/images/logo/learn.svg'
|
||||
|
@ -29,7 +30,7 @@ export const Logo = (props: Props) => {
|
|||
)
|
||||
.with(
|
||||
P.when(p => p.startsWith('/blog')),
|
||||
() => <Image src={logoSrc} alt="Status logo" />
|
||||
() => <Image src={logoBlogSrc} alt="Status logo" />
|
||||
)
|
||||
.otherwise(() => (
|
||||
<Image src={logoSrc} alt="Status logo" />
|
||||
|
|
|
@ -21,9 +21,9 @@ import {
|
|||
QrCodeIcon,
|
||||
} from '@status-im/icons'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import Head from 'next/head'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
import { Head } from '@/components/head'
|
||||
import { ERROR_CODES } from '@/consts/error-codes'
|
||||
import { useURLData } from '@/hooks/use-url-data'
|
||||
import { getRequestClient } from '@/lib/request-client'
|
||||
|
@ -80,6 +80,12 @@ export type Data =
|
|||
info: UserInfo
|
||||
}
|
||||
|
||||
const ACTION_VERB: Record<Type, string> = {
|
||||
community: 'Join',
|
||||
channel: 'View',
|
||||
profile: 'Open',
|
||||
}
|
||||
|
||||
const INSTRUCTIONS_HEADING: Record<Type, string> = {
|
||||
community: 'How to join this community:',
|
||||
channel: 'How to join this channel:',
|
||||
|
@ -93,7 +99,7 @@ const JOIN_BUTTON_LABEL: Record<Type, string> = {
|
|||
}
|
||||
|
||||
export function PreviewPage(props: PreviewPageProps) {
|
||||
const { type, decodedData, encodedData } = props
|
||||
const { type, decodedData, encodedData, index } = props
|
||||
|
||||
const { asPath } = useRouter()
|
||||
|
||||
|
@ -216,9 +222,34 @@ export function PreviewPage(props: PreviewPageProps) {
|
|||
return <ErrorPage errorCode={ERROR_CODES.NOT_FOUND} />
|
||||
}
|
||||
|
||||
// const urlOrigin = process.env.VERCEL_URL
|
||||
// ? 'https://' + process.env.VERCEL_URL
|
||||
// : ''
|
||||
|
||||
if ((loading && !data) || !data || !publicKey) {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<meta property="og:url" content={`https://status.app${asPath}`} />
|
||||
{/* todo: test if server-rendered version with which a (social) card would be
|
||||
generated would not effectively override actual shared link on clicking */}
|
||||
{/* <meta
|
||||
property="og:image"
|
||||
content={`${urlOrigin}/assets/preview/entity.png`}
|
||||
key="og:image"
|
||||
/> */}
|
||||
<meta
|
||||
property="al:ios:url"
|
||||
content={`https://status.app${asPath}`}
|
||||
key="al:ios:url"
|
||||
/>
|
||||
<meta
|
||||
property="al:android:url"
|
||||
content={`https://status.app${asPath}`}
|
||||
key="al:android:url"
|
||||
/>
|
||||
{!index && <meta name="robots" content="noindex" />}
|
||||
</Head>
|
||||
<div className="h-full xl:grid xl:grid-cols-[560px,auto]">
|
||||
<div className="pb-10">
|
||||
<div className="mx-auto px-5 pt-20 xl:px-20">
|
||||
|
@ -326,10 +357,33 @@ export function PreviewPage(props: PreviewPageProps) {
|
|||
|
||||
return (
|
||||
<>
|
||||
<Head index={props.index} />
|
||||
<Head>
|
||||
<title>
|
||||
{`${ACTION_VERB[type]} ${data.info.displayName} in Status`}
|
||||
</title>
|
||||
|
||||
<meta property="og:url" content={`https://status.app${asPath}`} />
|
||||
<meta
|
||||
property="og:title"
|
||||
content={`${ACTION_VERB[type]} ${data.info.displayName} in Status`}
|
||||
/>
|
||||
{/* <meta
|
||||
property="og:image"
|
||||
content={`${urlOrigin}/assets/preview/entity.png`}
|
||||
key="og:image"
|
||||
/> */}
|
||||
<meta property="og:description" content={data.info.description} />
|
||||
<meta
|
||||
name="apple-itunes-app"
|
||||
content={`app-id=1178893006, app-argument=status-app://${asPath.replace(
|
||||
/\//,
|
||||
''
|
||||
)}`}
|
||||
/>
|
||||
{!index && <meta name="robots" content="noindex" />}
|
||||
</Head>
|
||||
<>
|
||||
{/* todo: theme; based on user system settings */}
|
||||
{/* todo: (system or both?) install banner */}
|
||||
<div
|
||||
style={!bannerURL ? getGradientStyles(data) : undefined}
|
||||
className="relative h-full bg-gradient-to-b from-[var(--gradient-color)] to-[#fff] to-20% xl:grid xl:grid-cols-[560px,auto]"
|
||||
|
|
|
@ -4,6 +4,9 @@ import '@/styles/nav-nested-links.css'
|
|||
import { ThemeProvider } from '@status-im/components'
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import { Inter } from 'next/font/google'
|
||||
import Head from 'next/head'
|
||||
import { useRouter } from 'next/router'
|
||||
import { match, P } from 'ts-pattern'
|
||||
|
||||
import type { Page, PageLayout } from 'next'
|
||||
import type { AppProps } from 'next/app'
|
||||
|
@ -23,11 +26,122 @@ type Props = AppProps & {
|
|||
export default function App({ Component, pageProps }: Props) {
|
||||
const getLayout: PageLayout = Component.getLayout || (page => page)
|
||||
|
||||
// const urlOrigin = process.env.VERCEL_URL
|
||||
// ? 'https://' + process.env.VERCEL_URL
|
||||
// : ''
|
||||
|
||||
const { pathname, asPath } = useRouter()
|
||||
|
||||
return (
|
||||
<div id="app" className={inter.variable + ' font-sans'}>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<ThemeProvider>{getLayout(<Component {...pageProps} />)}</ThemeProvider>
|
||||
</QueryClientProvider>
|
||||
</div>
|
||||
<>
|
||||
<Head>
|
||||
<title>Status - Private, Secure Communication</title>
|
||||
|
||||
<meta name="title" content="Status - Private, Secure Communication" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Status brings the power of Ethereum into your pocket by combining a messenger, crypto-wallet, and Web3 browser."
|
||||
/>
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content={`https://status.app${asPath}`} />
|
||||
<meta
|
||||
property="og:title"
|
||||
content="Status - Private, Secure Communication"
|
||||
/>
|
||||
<meta
|
||||
property="og:description"
|
||||
content="Status brings the power of Ethereum into your pocket by combining a messenger, crypto-wallet, and Web3 browser."
|
||||
/>
|
||||
{/* <meta
|
||||
property="og:image"
|
||||
content={`${urlOrigin}/assets/preview/page.png`}
|
||||
key="og:image"
|
||||
/> */}
|
||||
<meta property="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:site" content="@ethstatus" />
|
||||
<meta name="apple-itunes-app" content="app-id=1178893006" />
|
||||
<meta
|
||||
property="al:ios:url"
|
||||
content={`https://status.app${asPath}`}
|
||||
key="al:ios:url"
|
||||
/>
|
||||
<meta property="al:ios:app_store_id" content="1178893006" />
|
||||
<meta
|
||||
property="al:ios:app_name"
|
||||
content="Status — Ethereum. Anywhere"
|
||||
/>
|
||||
<meta
|
||||
property="al:android:url"
|
||||
content={`https://status.app${asPath}`}
|
||||
key="al:android:url"
|
||||
/>
|
||||
<meta property="al:android:package" content="im.status.ethereum" />
|
||||
<meta
|
||||
property="al:android:app_name"
|
||||
content="Status — Ethereum. Anywhere"
|
||||
/>
|
||||
<meta
|
||||
property="article:publisher"
|
||||
content="https://www.facebook.com/ethstatus"
|
||||
/>
|
||||
{match(pathname)
|
||||
.with(
|
||||
P.when(p => p.startsWith('/insights')),
|
||||
() => (
|
||||
<>
|
||||
<link rel="icon" href="/assets/favicon/dev.png" />
|
||||
{/* <link rel="apple-touch-icon" href="/assets/favicon/dev.png" />
|
||||
<link
|
||||
rel="apple-touch-icon-precomposed"
|
||||
href="/assets/favicon/dev.png"
|
||||
/> */}
|
||||
</>
|
||||
)
|
||||
)
|
||||
.with(
|
||||
P.when(p => p.startsWith('/learn')),
|
||||
() => (
|
||||
<>
|
||||
<link rel="icon" href="/assets/favicon/learn.png" />
|
||||
{/* <link rel="apple-touch-icon" href="/assets/favicon/learn.png" />
|
||||
<link
|
||||
rel="apple-touch-icon-precomposed"
|
||||
href="/assets/favicon/learn.png"
|
||||
/> */}
|
||||
</>
|
||||
)
|
||||
)
|
||||
.with(
|
||||
P.when(p => p.startsWith('/blog')),
|
||||
() => (
|
||||
<>
|
||||
<link rel="icon" href="/assets/favicon/blog.png" />
|
||||
{/* <link rel="apple-touch-icon" href="/assets/favicon/blog.png" />
|
||||
<link
|
||||
rel="apple-touch-icon-precomposed"
|
||||
href="/assets/favicon/blog.png"
|
||||
/> */}
|
||||
</>
|
||||
)
|
||||
)
|
||||
.otherwise(() => (
|
||||
<>
|
||||
<link rel="icon" href="/assets/favicon/default.png" />
|
||||
{/* <link rel="apple-touch-icon" href="/assets/favicon/default.png" />
|
||||
<link
|
||||
rel="apple-touch-icon-precomposed"
|
||||
href="/assets/favicon/default.png"
|
||||
/> */}
|
||||
</>
|
||||
))}
|
||||
</Head>
|
||||
<div id="app" className={inter.variable + ' font-sans'}>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<ThemeProvider>
|
||||
{getLayout(<Component {...pageProps} />)}
|
||||
</ThemeProvider>
|
||||
</QueryClientProvider>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ export default class Document extends NextDocument {
|
|||
id="tamagui"
|
||||
dangerouslySetInnerHTML={{ __html: Tamagui.getCSS() }}
|
||||
/>
|
||||
<meta name="theme-color" content="#09101C" />
|
||||
</Head>
|
||||
<body>
|
||||
<Main />
|
||||
|
|
|
@ -223,7 +223,7 @@ const BlogDetailPage: Page<Props> = ({ post, relatedPosts }) => {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{relatedPosts.length && (
|
||||
{relatedPosts.length > 0 && (
|
||||
<div className="border-t border-neutral-10 bg-neutral-5 px-5 pb-[64px] pt-12 lg:px-10">
|
||||
<div className="mb-6">
|
||||
<Text size={27} weight="semibold">
|
||||
|
|
Loading…
Reference in New Issue