og-images-generator
Advanced tools
Comparing version 0.0.0 to 0.0.1
{ | ||
"name": "og-images-generator", | ||
"version": "0.0.0", | ||
"version": "0.0.1", | ||
"description": "Generate OG images from a static folder. Extract metadata from HTML pages. No headless browser involved.", | ||
@@ -49,2 +49,3 @@ "keywords": [ | ||
"@types/node": "^20.11.16", | ||
"@types/react": "^18.2.55", | ||
"prettier": "^3.2.5", | ||
@@ -51,0 +52,0 @@ "typedoc": "^0.25.7", |
118
README.md
@@ -14,14 +14,114 @@ # og-images-generator | ||
## Installation | ||
``` | ||
npm i og-images-generator | ||
``` | ||
Create a `og-images.config.js` in your current workspace root. | ||
See [demos/vanilla/og-images.config.js](./demos/vanilla/og-images.config.js) for a full working example. | ||
The gist is: | ||
```js | ||
// ./og-images.config.js | ||
import { | ||
html, | ||
styled, | ||
OG_DIMENSIONS, | ||
SOURCE_SANS_FONT, | ||
} from 'og-images-generator'; | ||
/** @type {import('og-images-generator').RenderOptions} */ | ||
export const renderOptions = { | ||
satori: { fonts: [await SOURCE_SANS_FONT()], ...OG_DIMENSIONS }, | ||
}; | ||
/** @type {import('og-images-generator').Template} */ | ||
export const template = ({ metadata }) => { | ||
if ('og:title' in metadata === false) throw Error('Missing title!'); | ||
if ('og:description' in metadata === false) | ||
throw Error('Missing description!'); | ||
const title = metadata['og:title']; | ||
const description = metadata['og:description']; | ||
return html` <!-- --> | ||
<div style=${styles.container}> | ||
<div style=${styles.foo}> | ||
${icon.main} | ||
<!-- ... --> | ||
</div> | ||
</div>`; | ||
}; | ||
const tokens = { | ||
primaryColor: `rgb(82,245,187)`, | ||
}; | ||
const icons = { | ||
main: html` | ||
<svg> | ||
<!-- ... --> | ||
</svg> | ||
`, | ||
}; | ||
const styles = { | ||
container: styled.div` | ||
display: flex; | ||
height: 100%; | ||
width: 100%; | ||
/* ... */ | ||
`, | ||
foo: styled.div` | ||
display: flex; | ||
color: ${tokens.primaryColor}; | ||
/* ... */ | ||
`, | ||
}; | ||
``` | ||
**You need to export** `renderOptions` and `template` from your `og-images-generator` configuration file. | ||
> [!NOTE] | ||
> `styled.div` is a dummy strings concatenation literal (to get syntax highlighting). | ||
> `div` is the only needed (and available) tag, as it makes no difference anyway. | ||
> | ||
> Also, you don't need to wrap interpolated HTML attributes with quotes (e.g. `style="${foo}"`). | ||
> `<foo-bar style=${styles.baz}></foo-bar>` just works. | ||
--- | ||
``` | ||
> [!TIP] | ||
> Recommended VS Code extensions: | ||
> | ||
> - Styled Components for inline CSS highlighting: `styled-components.vscode-styled-components` | ||
> - HTML highlighting: `bierner.lit-html` | ||
## Usage | ||
- [API documentation](https://juliancataldo.github.io/og-images-generator/) | ||
- [Demo projects](./demos) | ||
### CLI | ||
```sh | ||
npx generate-og | ||
# defaults to | ||
npx generate-og --base dist --out dist/og --json dist/og/index.json | ||
``` | ||
**Other projects 👀**… | ||
### Programmatic (JS API) | ||
- [retext-case-police](https://github.com/JulianCataldo/retext-case-police): Check popular names casing. Example: ⚠️ `github` → ✅ `GitHub`. | ||
- [remark-lint-frontmatter-schema](https://github.com/JulianCataldo/remark-lint-frontmatter-schema): Validate your Markdown **frontmatter** data against a **JSON schema**. | ||
- [JSON Schema Form Element](https://github.com/json-schema-form-element/jsfe): Effortless forms, with standards. | ||
```js | ||
import { generateOgImages } from 'og-images-generator/api'; | ||
await generateOgImages(/* options */); | ||
``` | ||
## References | ||
@@ -36,2 +136,10 @@ | ||
**Other projects 👀**… | ||
- [retext-case-police](https://github.com/JulianCataldo/retext-case-police): Check popular names casing. Example: ⚠️ `github` → ✅ `GitHub`. | ||
- [remark-lint-frontmatter-schema](https://github.com/JulianCataldo/remark-lint-frontmatter-schema): Validate your Markdown **frontmatter** data against a **JSON schema**. | ||
- [JSON Schema Form Element](https://github.com/json-schema-form-element/jsfe): Effortless forms, with standards. | ||
--- | ||
<div align="center"> | ||
@@ -38,0 +146,0 @@ |
@@ -14,5 +14,9 @@ /** | ||
export { html } from '@lit-labs/ssr'; | ||
export { styled } from './dummy-literals.js'; | ||
// NOTE: Just `export { html } from '@lit-labs/ssr';` will not show in TypeDoc. | ||
// FIXME: Also, `html` produce a 404, see https://github.com/TypeStrong/typedoc/issues/2497 | ||
import { html as litHtml } from '@lit-labs/ssr'; | ||
export const html = litHtml; | ||
/** | ||
@@ -19,0 +23,0 @@ * @typedef {import('@lit-labs/ssr').ServerRenderedTemplate} LitServerTemplate |
@@ -14,6 +14,6 @@ import satori from 'satori'; | ||
export const OG_DIMENSIONS = { | ||
export const OG_DIMENSIONS = /** @type {const} */ ({ | ||
width: 1200, | ||
height: 630, | ||
}; | ||
}); | ||
@@ -55,3 +55,5 @@ const SOURCE_SANS_FONT_URL = | ||
const litSsred = collectResultSync(renderLit(template)); | ||
const satoried = satoriHtml(litSsred); | ||
const satoried = /** @type {import('react').ReactNode} Cast VNode */ ( | ||
satoriHtml(litSsred) | ||
); | ||
@@ -58,0 +60,0 @@ const svg = await satori(satoried, userConfig.renderOptions.satori); |
@@ -1,3 +0,3 @@ | ||
export { html } from "@lit-labs/ssr"; | ||
export { styled } from "./dummy-literals.js"; | ||
export const html: typeof litHtml; | ||
export type MetadataCollection = import('./collect.js').Metadata; | ||
@@ -10,3 +10,4 @@ export type RenderOptions = import('./render.js').RenderOptions; | ||
export type Template = (options: TemplateOptions) => LitServerTemplate; | ||
import { html as litHtml } from '@lit-labs/ssr'; | ||
export { fetchFont, OG_DIMENSIONS, SOURCE_SANS_FONT } from "./render.js"; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -23,4 +23,4 @@ /** | ||
export namespace OG_DIMENSIONS { | ||
let width: number; | ||
let height: number; | ||
let width: 1200; | ||
let height: 630; | ||
} | ||
@@ -27,0 +27,0 @@ export function SOURCE_SANS_FONT(): Promise<{ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
25378
607
154
5