Skip to content

Commit

Permalink
Merge branch 'main' of github.com:blockscout/frontend into tom2drum/i…
Browse files Browse the repository at this point in the history
…ssue-1157
  • Loading branch information
tom2drum committed Sep 25, 2023
2 parents 5bc66da + 2a5e42a commit 5880692
Show file tree
Hide file tree
Showing 236 changed files with 1,102 additions and 287 deletions.
3 changes: 2 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID=xxx
NEXT_PUBLIC_RE_CAPTCHA_APP_SITE_KEY=xxx
NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID=UA-XXXXXX-X
NEXT_PUBLIC_MIXPANEL_PROJECT_TOKEN=xxx
NEXT_PUBLIC_AUTH0_CLIENT_ID=xxx
NEXT_PUBLIC_AUTH0_CLIENT_ID=xxx
NEXT_PUBLIC_FAVICON_GENERATOR_API_KEY=xxx
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('NEXT_PUBLIC_PROMOTE_BLOCKSCOUT_IN_TITLE') || 'true',
og: {
description: getEnvValue('NEXT_PUBLIC_OG_DESCRIPTION') || '',
imageUrl: getExternalAssetFilePath('NEXT_PUBLIC_OG_IMAGE_URL') || defaultImageUrl,
},
});

export default meta;
16 changes: 16 additions & 0 deletions configs/app/ui/views/address.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { IdenticonType } from 'types/views/address';
import { IDENTICON_TYPES } from 'types/views/address';

import { getEnvValue } from 'configs/app/utils';

const identiconType: IdenticonType = (() => {
const value = getEnvValue('NEXT_PUBLIC_VIEWS_ADDRESS_IDENTICON_TYPE');

return IDENTICON_TYPES.find((type) => value === type) || 'jazzicon';
})();

const config = Object.freeze({
identiconType: identiconType,
});

export default config;
1 change: 1 addition & 0 deletions configs/app/ui/views/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { default as block } from './block';
export { default as address } from './address';
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
2 changes: 2 additions & 0 deletions configs/envs/.env.main.L2
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ NEXT_PUBLIC_NETWORK_LOGO=https://raw.githubusercontent.com/blockscout/frontend-c
NEXT_PUBLIC_NETWORK_ICON=https://raw.githubusercontent.com/blockscout/frontend-configs/dev/configs/network-icons/base.svg
## footer
## misc
## views
NEXT_PUBLIC_VIEWS_ADDRESS_IDENTICON_TYPE=gradient_avatar

# app features
NEXT_PUBLIC_APP_INSTANCE=local
Expand Down
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
5 changes: 5 additions & 0 deletions deploy/tools/envs-validator/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { SUPPORTED_WALLETS } from '../../../types/client/wallets';
import type { CustomLink, CustomLinksGroup } from '../../../types/footerLinks';
import type { ChainIndicatorId } from '../../../types/homepage';
import { type NetworkVerificationType, type NetworkExplorer, type FeaturedNetwork, NETWORK_GROUPS } from '../../../types/networks';
import { IDENTICON_TYPES } from '../../../types/views/address';
import { BLOCK_FIELDS_IDS } from '../../../types/views/block';
import type { BlockFieldId } from '../../../types/views/block';

Expand Down Expand Up @@ -294,6 +295,7 @@ const schema = yup
.transform(getEnvValue)
.json()
.of(yup.string<BlockFieldId>().oneOf(BLOCK_FIELDS_IDS)),
NEXT_PUBLIC_VIEWS_ADDRESS_IDENTICON_TYPE: yup.string().oneOf(IDENTICON_TYPES),

// e. misc
NEXT_PUBLIC_NETWORK_EXPLORERS: yup
Expand Down Expand Up @@ -323,6 +325,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
2 changes: 2 additions & 0 deletions deploy/values/review/values.yaml.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,5 @@ frontend:
_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_WEB3_WALLETS:
_default: "['token_pocket','coinbase','metamask']"
NEXT_PUBLIC_VIEWS_ADDRESS_IDENTICON_TYPE:
_default: gradient_avatar
21 changes: 21 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

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 All @@ -163,6 +176,14 @@ By default, the app has generic favicon. You can override this behavior by provi

&nbsp;

#### Address views

| Variable | Type | Description | Compulsoriness | Default value | Example value |
| --- | --- | --- | --- | --- | --- |
| NEXT_PUBLIC_VIEWS_ADDRESS_IDENTICON_TYPE | `"github" \| "jazzicon" \| "gradient_avatar" \| "blockie"` | Style of address identicon appearance. Choose between [GitHub](https://github.blog/2013-08-14-identicons/), [Metamask Jazzicon](https://metamask.github.io/jazzicon/), [Gradient Avatar](https://github.com/varld/gradient-avatar) and [Ethereum Blocky](https://mycryptohq.github.io/ethereum-blockies-base64/) | - | `jazzicon` | `gradient_avatar` |

&nbsp;

### Misc

| Variable | Type| Description | Compulsoriness | Default value | Example value |
Expand Down
5 changes: 2 additions & 3 deletions icons/contract.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion icons/nft_shield.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion icons/social/canny.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@
"d3": "^7.6.1",
"dayjs": "^1.11.5",
"dom-to-image": "^2.6.0",
"ethereum-blockies-base64": "^1.0.2",
"framer-motion": "^6.5.1",
"gradient-avatar": "^1.0.2",
"graphiql": "^2.2.0",
"graphql": "^16.6.0",
"graphql-ws": "^5.11.3",
Expand Down
Loading

0 comments on commit 5880692

Please sign in to comment.