Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

og improvements #1175

Merged
merged 4 commits into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions configs/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import api from './api';
import app from './app';
import chain from './chain';
import * as features from './features';
import meta from './meta';
import services from './services';
import UI from './ui';

Expand All @@ -12,6 +13,7 @@ const config = Object.freeze({
UI,
features,
services,
meta,
});

export default config;
14 changes: 14 additions & 0 deletions configs/app/meta.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import app from './app';
import { getEnvValue, getExternalAssetFilePath } from './utils';

const defaultImageUrl = app.baseUrl + '/static/og_placeholder.png';

const meta = Object.freeze({
promoteBlockscoutInTitle: getEnvValue(process.env.NEXT_PUBLIC_PROMOTE_BLOCKSCOUT_IN_TITLE) || 'true',
og: {
description: getEnvValue(process.env.NEXT_PUBLIC_OG_DESCRIPTION) || '',
imageUrl: getExternalAssetFilePath('NEXT_PUBLIC_OG_IMAGE_URL', process.env.NEXT_PUBLIC_OG_IMAGE_URL) || defaultImageUrl,
},
});

export default meta;
3 changes: 3 additions & 0 deletions configs/envs/.env.eth
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,6 @@ NEXT_PUBLIC_STATS_API_HOST=https://stats-eth-main.k8s.blockscout.com
NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com

#meta
NEXT_PUBLIC_OG_IMAGE_URL=https://github.com/blockscout/frontend-configs/blob/main/configs/og-images/eth.jpg?raw=true
3 changes: 3 additions & 0 deletions configs/envs/.env.eth_goerli
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,6 @@ NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_WEB3_WALLETS=['token_pocket','metamask']

#meta
NEXT_PUBLIC_OG_IMAGE_URL=https://github.com/blockscout/frontend-configs/blob/main/configs/og-images/eth-goerli.png?raw=true
isstuev marked this conversation as resolved.
Show resolved Hide resolved
5 changes: 4 additions & 1 deletion configs/envs/.env.polygon
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,7 @@ NEXT_PUBLIC_APP_ENV=development
NEXT_PUBLIC_HAS_BEACON_CHAIN=false
# NEXT_PUBLIC_STATS_API_HOST=https://stats-rsk-testnet.k8s.blockscout.com
NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com
NEXT_PUBLIC_WEB3_WALLETS=['token_pocket','metamask']
NEXT_PUBLIC_WEB3_WALLETS=['token_pocket','metamask']

#meta
NEXT_PUBLIC_OG_IMAGE_URL=https://github.com/blockscout/frontend-configs/blob/main/configs/og-images/polygon-mainnet.png?raw=true
3 changes: 3 additions & 0 deletions configs/envs/.env.rootstock
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,6 @@ NEXT_PUBLIC_GRAPHIQL_TRANSACTION=0x97fa753626b8d44011d0b9f9a947c735f20b6e895efde
NEXT_PUBLIC_HAS_BEACON_CHAIN=false
NEXT_PUBLIC_STATS_API_HOST=https://stats-rsk-testnet.k8s.blockscout.com
NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com

#meta
NEXT_PUBLIC_OG_IMAGE_URL=https://github.com/blockscout/frontend-configs/blob/main/configs/og-images/rootstock-testnet.png?raw=true
1 change: 1 addition & 0 deletions deploy/scripts/download_assets.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ ASSETS_ENVS=(
"NEXT_PUBLIC_NETWORK_LOGO_DARK"
"NEXT_PUBLIC_NETWORK_ICON"
"NEXT_PUBLIC_NETWORK_ICON_DARK"
"NEXT_PUBLIC_OG_IMAGE_URL"
)

# Create the assets directory if it doesn't exist
Expand Down
3 changes: 3 additions & 0 deletions deploy/tools/envs-validator/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,9 @@ const schema = yup
}),
NEXT_PUBLIC_WEB3_DISABLE_ADD_TOKEN_TO_WALLET: yup.boolean(),
NEXT_PUBLIC_AD_TEXT_PROVIDER: yup.string<AdTextProviders>().oneOf(SUPPORTED_AD_TEXT_PROVIDERS),
NEXT_PUBLIC_PROMOTE_BLOCKSCOUT_IN_TITLE: yup.boolean(),
NEXT_PUBLIC_OG_DESCRIPTION: yup.string(),
NEXT_PUBLIC_OG_IMAGE_URL: yup.string().url(),

// 6. External services envs
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: yup.string(),
Expand Down
2 changes: 2 additions & 0 deletions deploy/values/review-l2/values.yaml.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,5 @@ frontend:
_default: ref+vault://deployment-values/blockscout/dev/review-l2?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID
NEXT_PUBLIC_FAVICON_GENERATOR_API_KEY:
_default: ref+vault://deployment-values/blockscout/common?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_FAVICON_GENERATOR_API_KEY
NEXT_PUBLIC_OG_IMAGE_URL:
_default: https://github.com/blockscout/frontend-configs/blob/main/configs/og-images/base-goerli.png?raw=true
13 changes: 13 additions & 0 deletions docs/ENVS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ The app instance could be customized by passing following variables to NodeJS en
- [Sidebar](ENVS.md#sidebar)
- [Footer](ENVS.md#footer)
- [Favicon](ENVS.md#favicon)
- [Meta](ENVS.md#meta)
- [Views](ENVS.md#views)
- [Block](ENVS.md#block-views)
- [Misc](ENVS.md#misc)
Expand Down Expand Up @@ -145,6 +146,18 @@ By default, the app has generic favicon. You can override this behavior by provi

&nbsp;

### Meta
isstuev marked this conversation as resolved.
Show resolved Hide resolved

Settings for meta tags and OG tags

| Variable | Type| Description | Compulsoriness | Default value | Example value |
| --- | --- | --- | --- | --- | --- |
| NEXT_PUBLIC_PROMOTE_BLOCKSCOUT_IN_TITLE | `boolean` | Set to `true` to promote Blockscout in meta and OG titles | - | `true` | `true` |
| NEXT_PUBLIC_OG_DESCRIPTION | `string` | Custom OG description | - | - | `Blockscout is the #1 open-source blockchain explorer available today. 100+ chains and counting rely on Blockscout data availability, APIs, and ecosystem tools to support their networks.` |
| NEXT_PUBLIC_OG_IMAGE_URL | `string` | OG image url. Minimum image size is 200 x 20 pixels (recommended: 1200 x 600); maximum supported file size is 8 MB; 2:1 aspect ratio; supported formats: image/jpeg, image/gif, image/png | - | `static/og_placeholder.png` | `https://placekitten.com/1200/600` |

&nbsp;

### Views

#### Block views
Expand Down
15 changes: 15 additions & 0 deletions lib/metadata/__snapshots__/generate.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,35 @@
exports[`generates correct metadata for: dynamic route 1`] = `
{
"description": "View transaction 0x12345 on Blockscout (Blockscout) Explorer",
"opengraph": {
"description": "",
"imageUrl": "",
"title": "Blockscout transaction 0x12345 | Blockscout",
},
"title": "Blockscout transaction 0x12345 | Blockscout",
}
`;

exports[`generates correct metadata for: dynamic route with API data 1`] = `
{
"description": "0x12345, balances and analytics on the Blockscout (Blockscout) Explorer",
"opengraph": {
"description": "",
"imageUrl": "",
"title": "Blockscout USDT token details | Blockscout",
},
"title": "Blockscout USDT token details | Blockscout",
}
`;

exports[`generates correct metadata for: static route 1`] = `
{
"description": "Blockscout is the #1 open-source blockchain explorer available today. 100+ chains and counting rely on Blockscout data availability, APIs, and ecosystem tools to support their networks.",
"opengraph": {
"description": "",
"imageUrl": "http://localhost:3000/static/og_placeholder.png",
"title": "Blockscout blocks | Blockscout",
},
"title": "Blockscout blocks | Blockscout",
}
`;
13 changes: 11 additions & 2 deletions lib/metadata/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import config from 'configs/app';
import getNetworkTitle from 'lib/networks/getNetworkTitle';

import compileValue from './compileValue';
import getPageOgType from './getPageOgType';
import * as templates from './templates';

export default function generate<R extends Route>(route: R, apiData?: ApiData<R>): Metadata {
Expand All @@ -16,11 +17,19 @@ export default function generate<R extends Route>(route: R, apiData?: ApiData<R>
network_title: getNetworkTitle(),
};

const title = compileValue(templates.title.make(route.pathname), params);
const compiledTitle = compileValue(templates.title.make(route.pathname), params);
const title = compiledTitle ? compiledTitle + (config.meta.promoteBlockscoutInTitle ? ' | Blockscout' : '') : '';
const description = compileValue(templates.description.make(route.pathname), params);

const pageOgType = getPageOgType(route.pathname);

return {
title,
title: title,
description,
opengraph: {
title: title,
description: pageOgType !== 'Regular page' ? config.meta.og.description : '',
imageUrl: pageOgType !== 'Regular page' ? config.meta.og.imageUrl : '',
},
};
}
52 changes: 52 additions & 0 deletions lib/metadata/getPageOgType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import type { Route } from 'nextjs-routes';

type OGPageType = 'Homepage' | 'Root page' | 'Regular page';

const OG_TYPE_DICT: Record<Route['pathname'], OGPageType> = {
'/': 'Homepage',
'/txs': 'Root page',
'/tx/[hash]': 'Regular page',
'/blocks': 'Root page',
'/block/[height_or_hash]': 'Regular page',
'/accounts': 'Root page',
'/address/[hash]': 'Regular page',
'/verified-contracts': 'Root page',
'/address/[hash]/contract-verification': 'Regular page',
'/tokens': 'Root page',
'/token/[hash]': 'Regular page',
'/token/[hash]/instance/[id]': 'Regular page',
'/apps': 'Root page',
'/apps/[id]': 'Regular page',
'/stats': 'Root page',
'/api-docs': 'Regular page',
'/graphiql': 'Regular page',
'/search-results': 'Regular page',
'/auth/profile': 'Root page',
'/account/watchlist': 'Regular page',
'/account/api-key': 'Regular page',
'/account/custom-abi': 'Regular page',
'/account/public-tags-request': 'Regular page',
'/account/tag-address': 'Regular page',
'/account/verified-addresses': 'Root page',
'/withdrawals': 'Root page',
'/visualize/sol2uml': 'Regular page',
'/csv-export': 'Regular page',
'/l2-deposits': 'Root page',
'/l2-output-roots': 'Root page',
'/l2-txn-batches': 'Root page',
'/l2-withdrawals': 'Root page',
'/404': 'Regular page',

// service routes, added only to make typescript happy
'/login': 'Regular page',
'/api/media-type': 'Regular page',
'/api/proxy': 'Regular page',
'/api/csrf': 'Regular page',
'/api/healthz': 'Regular page',
'/auth/auth0': 'Regular page',
'/auth/unverified-email': 'Regular page',
};

export default function getPageOgType(pathname: Route['pathname']) {
return OG_TYPE_DICT[pathname];
}
2 changes: 1 addition & 1 deletion lib/metadata/templates/title.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,5 @@ const TEMPLATE_MAP: Record<Route['pathname'], string> = {
export function make(pathname: Route['pathname']) {
const template = TEMPLATE_MAP[pathname];

return `%network_name% ${ template } | Blockscout`;
return `%network_name% ${ template }`;
}
5 changes: 5 additions & 0 deletions lib/metadata/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,9 @@ never;
export interface Metadata {
title: string;
description: string;
opengraph: {
title: string;
description?: string;
imageUrl?: string;
};
}
8 changes: 7 additions & 1 deletion nextjs/PageNextJs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type Props = Route & {
}

const PageNextJs = (props: Props) => {
const { title, description } = metadata.generate(props);
const { title, description, opengraph } = metadata.generate(props);

useGetCsrfToken();
useAdblockDetect();
Expand All @@ -28,6 +28,12 @@ const PageNextJs = (props: Props) => {
<Head>
<title>{ title }</title>
<meta name="description" content={ description }/>

{ /* OG TAGS */ }
<meta property="og:title" content={ opengraph.title }/>
{ opengraph.description && <meta property="og:description" content={ opengraph.description }/> }
<meta property="og:image" content={ opengraph.imageUrl }/>
<meta property="og:type" content="website"/>
</Head>
{ props.children }
</>
Expand Down
14 changes: 0 additions & 14 deletions pages/_document.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import React from 'react';

import * as serverTiming from 'nextjs/utils/serverTiming';

import config from 'configs/app';
import theme from 'theme';

class MyDocument extends Document {
Expand Down Expand Up @@ -46,19 +45,6 @@ class MyDocument extends Document {
<link rel="icon" sizes="16x16" type="image/png"href="/favicon/favicon-16x16.png"/>
<link rel="apple-touch-icon" href="/favicon/apple-touch-icon-180x180.png"/>
<link rel="mask-icon" href="/favicon/safari-pinned-tab.svg"/>

{ /* OG TAGS */ }
<meta property="og:title" content="Blockscout: A block explorer designed for a decentralized world."/>
<meta
property="og:description"
// eslint-disable-next-line max-len
content="Blockscout is the #1 open-source blockchain explorer available today. 100+ chains and counting rely on Blockscout data availability, APIs, and ecosystem tools to support their networks."
/>
<meta property="og:image" content={ config.app.baseUrl + '/static/og.png' }/>
<meta property="og:site_name" content="Blockscout"/>
<meta property="og:type" content="website"/>
<meta name="twitter:card" content="summary_large_image"/>
<meta property="twitter:image" content={ config.app.baseUrl + '/static/og_twitter.png' }/>
</Head>
<body>
<ColorModeScript initialColorMode={ theme.config.initialColorMode }/>
Expand Down
Binary file removed public/static/og.png
Binary file not shown.
Binary file added public/static/og_placeholder.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading