Skip to content

Commit

Permalink
Library preview for og:image generation (#236)
Browse files Browse the repository at this point in the history
* feat: add LibraryPreview component

* feat: pass props to Meta component

* feat: add LibraryPreviewPage

* feat: add update-og-images script

* feat: temporary disable og:image override
  • Loading branch information
teleginzhenya authored Jul 22, 2024
1 parent e7a960a commit 451a216
Show file tree
Hide file tree
Showing 15 changed files with 3,811 additions and 1,795 deletions.
5,181 changes: 3,421 additions & 1,760 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"url": "^0.11.0"
},
"devDependencies": {
"@aws-sdk/client-s3": "^3.614.0",
"@gravity-ui/eslint-config": "^2.0.0",
"@gravity-ui/prettier-config": "^1.0.1",
"@gravity-ui/stylelint-config": "^2.0.0",
Expand All @@ -62,6 +63,7 @@
"gh-pages": "^4.0.0",
"next-compose-plugins": "^2.2.1",
"next-transpile-modules": "^10.0.1",
"playwright": "^1.45.2",
"prettier": "^2.7.1",
"raw-loader": "^4.0.2",
"sass": "^1.56.1",
Expand All @@ -79,6 +81,7 @@
"fetch-contributors": "node ./scripts/prefetch-contributors.mjs",
"get-packages-versions": "node ./scripts/get-packages-versions.mjs",
"prepare-metadata": "npm run fetch-data && npm run fetch-contributors && npm run get-packages-versions",
"update-og-images": "node ./scripts/update-og-images.mjs",
"prestart": "npm run prepare-metadata",
"prebuild": "npm run prepare-metadata",
"pretest": "npm run prepare-metadata",
Expand Down
51 changes: 51 additions & 0 deletions scripts/update-og-images.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import {PutObjectCommand, S3} from '@aws-sdk/client-s3';
import * as dotenv from 'dotenv';
import {chromium} from 'playwright';

import {libs} from '../src/libs.mjs';

dotenv.config();

const s3Client = new S3({
endpoint: 'https://storage.yandexcloud.net/',
credentials: {
accessKeyId: process.env.S3_ACCESS_KEY_ID,
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
},
region: 'ru-central1-a',
});

const BUCKET_NAME = 'gravity-assets';

try {
const browser = await chromium.launch();
const context = await browser.newContext({
viewport: {width: 1200, height: 630},
});
const page = await context.newPage();

for (let i = 0; i < libs.length; i++) {
const {id} = libs[i];
await page.goto(`https://gravity-ui.com/libraries/${id}/preview`, {
waitUntil: 'networkidle',
});
const buffer = await page.screenshot();

const uploadParams = {
Bucket: BUCKET_NAME,
Key: `og/${id}.jpg`,
ContentType: 'image/jpeg',
Body: buffer,
};

try {
await s3Client.send(new PutObjectCommand(uploadParams));
} catch (err) {
console.error(err);
}
}

await browser.close();
} catch (err) {
console.error(err);
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import {GetStaticPaths, GetStaticPathsResult, GetStaticProps} from 'next';
import {useTranslation} from 'next-i18next';

import {Layout} from '../../components/Layout/Layout';
import {Library} from '../../components/Library/Library';
import {useLocaleRedirect} from '../../hooks/useLocaleRedirect';
import {getI18nPaths, getI18nProps, getLibById, getLibsList} from '../../utils';
import {Layout} from '../../../components/Layout/Layout';
import {Library} from '../../../components/Library/Library';
import {useLocaleRedirect} from '../../../hooks/useLocaleRedirect';
import {getI18nPaths, getI18nProps, getLibById, getLibsList} from '../../../utils';

// function getOgImageUrl(id?: string) {
// return id ? `https://storage.yandexcloud.net/gravity-assets/og/${id}.jpg` : undefined;
// }

const libs = getLibsList();

Expand Down Expand Up @@ -33,12 +38,21 @@ export const getStaticProps: GetStaticProps = async (ctx) => {
};

export const LibraryPage = ({libId}: {libId: string}) => {
const {t} = useTranslation();
useLocaleRedirect();

const lib = getLibById(libId);

return (
<Layout title={lib?.config.title ?? ''}>
<Layout
title={lib?.config.title ?? ''}
meta={{
name: lib?.config.title,
description: t(`libraries-info:description_${lib.config.id}`),
// TODO telegine@: temporary disabled untill images are ready
// image: getOgImageUrl(lib?.config.id),
}}
>
<Library lib={lib} />
</Layout>
);
Expand Down
55 changes: 55 additions & 0 deletions src/[locale]/libraries/[libId]/preview/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import {PageConstructorProvider, Theme} from '@gravity-ui/page-constructor';
import {GetStaticPaths, GetStaticPathsResult, GetStaticProps} from 'next';
import Head from 'next/head';
import React from 'react';
import {useLocaleRedirect} from 'src/hooks/useLocaleRedirect';

import {LibraryPreview} from '../../../../components/LibraryPreview/LibraryPreview';
import {getI18nPaths, getI18nProps, getLibsList} from '../../../../utils';

const theme = Theme.Dark;

const libs = getLibsList();

export const getStaticPaths: GetStaticPaths = async () => {
const paths = getI18nPaths().reduce<GetStaticPathsResult['paths']>((acc, localeItem) => {
acc.push(
...libs.map((libItem) => ({
params: {locale: localeItem.params.locale, libId: libItem.config.id},
})),
);
return acc;
}, []);

return {
paths,
fallback: false,
};
};

export const getStaticProps: GetStaticProps = async (context) => {
return {
props: {
id: context.params?.libId,
...(await getI18nProps(context, ['library', 'libraries-info'])),
},
};
};

export const LibraryPreviewPage = ({id}: {id: string}) => {
const lib = libs.find((item) => item.config.id === id)!;

Check warning on line 40 in src/[locale]/libraries/[libId]/preview/index.tsx

View workflow job for this annotation

GitHub Actions / deploy (18.x)

Forbidden non-null assertion

Check warning on line 40 in src/[locale]/libraries/[libId]/preview/index.tsx

View workflow job for this annotation

GitHub Actions / deploy (18.x)

Forbidden non-null assertion

Check warning on line 40 in src/[locale]/libraries/[libId]/preview/index.tsx

View workflow job for this annotation

GitHub Actions / Verify Files

Forbidden non-null assertion

Check warning on line 40 in src/[locale]/libraries/[libId]/preview/index.tsx

View workflow job for this annotation

GitHub Actions / deploy (18.x)

Forbidden non-null assertion

Check warning on line 40 in src/[locale]/libraries/[libId]/preview/index.tsx

View workflow job for this annotation

GitHub Actions / deploy (18.x)

Forbidden non-null assertion

Check warning on line 40 in src/[locale]/libraries/[libId]/preview/index.tsx

View workflow job for this annotation

GitHub Actions / deploy (18.x)

Forbidden non-null assertion

Check warning on line 40 in src/[locale]/libraries/[libId]/preview/index.tsx

View workflow job for this annotation

GitHub Actions / deploy (18.x)

Forbidden non-null assertion

Check warning on line 40 in src/[locale]/libraries/[libId]/preview/index.tsx

View workflow job for this annotation

GitHub Actions / deploy (18.x)

Forbidden non-null assertion

Check warning on line 40 in src/[locale]/libraries/[libId]/preview/index.tsx

View workflow job for this annotation

GitHub Actions / deploy (18.x)

Forbidden non-null assertion

Check warning on line 40 in src/[locale]/libraries/[libId]/preview/index.tsx

View workflow job for this annotation

GitHub Actions / deploy (18.x)

Forbidden non-null assertion

Check warning on line 40 in src/[locale]/libraries/[libId]/preview/index.tsx

View workflow job for this annotation

GitHub Actions / deploy (18.x)

Forbidden non-null assertion
useLocaleRedirect();

return (
<React.Fragment>
<Head>
<title>{lib?.config.title ?? ''} — og:image</title>
</Head>
<PageConstructorProvider theme={theme}>
<LibraryPreview lib={lib} />
</PageConstructorProvider>
</React.Fragment>
);
};

export default LibraryPreviewPage;
3 changes: 3 additions & 0 deletions src/assets/icons/preview-calendar.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/assets/icons/preview-star.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/assets/icons/preview-version.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions src/assets/logo-without-text.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 4 additions & 2 deletions src/components/Layout/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {Footer} from '../Footer/Footer';
import {Menu} from '../Menu/Menu';

import './Layout.scss';
import {Meta} from './Meta/Meta';
import {Meta, MetaProps} from './Meta/Meta';

TimeAgo.addDefaultLocale(en);
TimeAgo.addLocale(ru);
Expand All @@ -27,6 +27,7 @@ export type LayoutProps = {
isPageConstrucor?: boolean;
isRtl?: boolean;
showOnlyContent?: boolean;
meta?: MetaProps;
};

export const Layout: React.FC<LayoutProps> = ({
Expand All @@ -35,6 +36,7 @@ export const Layout: React.FC<LayoutProps> = ({
isPageConstrucor = false,
isRtl = false,
showOnlyContent = false,
meta = {},
}) => {
const {i18n} = useTranslation();

Expand Down Expand Up @@ -81,7 +83,7 @@ export const Layout: React.FC<LayoutProps> = ({
<EnvironmentContext.Provider value={{isClient, isRtl}}>
<Head>
<title>{`Gravity UI${title ? ` – ${title}` : ''}`}</title>
<Meta />
<Meta {...meta} />
</Head>
<ThemeProvider theme={DEFAULT_THEME} direction={isRtl ? 'rtl' : 'ltr'}>
{isPageConstrucor ? (
Expand Down
56 changes: 30 additions & 26 deletions src/components/Layout/Meta/Meta.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
import React from 'react';

export const Meta: React.FC = () => {
const DEFAULT_META = {
name: 'Gravity&nbsp;UI',
description: 'Build modern interfaces with the Gravity design system and libraries',
image: 'https://gravity-ui.com/index-social.png',
};

export type MetaProps = {
name?: string;
description?: string;
image?: string;
};

export const Meta: React.FC<MetaProps> = ({
name = DEFAULT_META.name,
description = DEFAULT_META.description,
image = DEFAULT_META.image,
}) => {
return (
<React.Fragment>
<meta charSet="utf-8" />
Expand All @@ -14,40 +30,28 @@ export const Meta: React.FC = () => {

<link rel="apple-touch-icon" href="/favicon-192x192.png" />

<meta
name="description"
content="Build modern interfaces with the Gravity design system and libraries "
/>
<meta name="description" content={description} />

<link data-react-helmet="true" rel="canonical" href="https://gravity-ui.com/" />

<meta itemProp="name" content="Gravity&nbsp;UI" />
<meta
itemProp="description"
content="Build modern interfaces with the Gravity design system and libraries"
/>
<meta itemProp="image" content="https://gravity-ui.com/index-social.png" />

<meta property="og:title" content="Gravity&nbsp;UI" />
<meta
property="og:description"
content="Build modern interfaces with the Gravity design system and libraries"
/>
<meta itemProp="name" content={name} />
<meta itemProp="description" content={description} />
<meta itemProp="image" content={image} />

<meta property="og:title" content={name} />
<meta property="og:description" content={description} />
<meta property="og:type" content="website" />
<meta property="og:site_name" content="Gravity&nbsp;UI" />
<meta property="og:site_name" content={name} />
<meta property="og:url" content="https://gravity-ui.com/" />
<meta property="og:image" content="https://gravity-ui.com/index-social.png" />
<meta property="og:image" content={image} />
<meta property="og:locale" content="en" />

<meta name="twitter:title" content="Gravity&nbsp;UI" />
<meta
name="twitter:description"
content="Build modern interfaces with the Gravity design system and libraries"
/>
<meta name="twitter:title" content={name} />
<meta name="twitter:description" content={description} />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:image" content="https://gravity-ui.com/index-social.png" />
<meta name="twitter:image" content={image} />

<meta property="share:title" content="Gravity&nbsp;UI" />
<meta property="share:title" content={name} />
<meta property="share:sharing_schema" content="default" />
<link rel="manifest" href="/manifest.json" />
</React.Fragment>
Expand Down
Loading

0 comments on commit 451a216

Please sign in to comment.