mirror of
https://github.com/LukeHagar/sveltekit-og.git
synced 2025-12-06 04:21:37 +00:00
Basic Docs and publish.yml changes for pnpm v
This commit is contained in:
2
.github/workflows/publish.yml
vendored
2
.github/workflows/publish.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
|||||||
name: Install pnpm
|
name: Install pnpm
|
||||||
id: pnpm-install
|
id: pnpm-install
|
||||||
with:
|
with:
|
||||||
version: 7
|
version: 8.6.1
|
||||||
- run: pnpm install
|
- run: pnpm install
|
||||||
- run: pnpm build
|
- run: pnpm build
|
||||||
#- run: pnpm test
|
#- run: pnpm test
|
||||||
|
|||||||
35
README.md
35
README.md
@@ -7,8 +7,9 @@ Dynamically generate Open Graph images from an HTML+CSS template or Svelte compo
|
|||||||
```bash
|
```bash
|
||||||
pnpm install -D @ethercorps/sveltekit-og
|
pnpm install -D @ethercorps/sveltekit-og
|
||||||
```
|
```
|
||||||
|
|
||||||
> Using with Cloudflare Pages or Workers then you have to provide `url` polyfill by just installing it as `devDependency`.
|
> Using with Cloudflare Pages or Workers then you have to provide `url` polyfill by just installing it as `devDependency`.
|
||||||
>
|
|
||||||
```bash
|
```bash
|
||||||
pnpm i -D url
|
pnpm i -D url
|
||||||
```
|
```
|
||||||
@@ -45,21 +46,21 @@ const fontFile = await fetch('https://og-playground.vercel.app/inter-latin-ext-4
|
|||||||
const fontData: ArrayBuffer = await fontFile.arrayBuffer();
|
const fontData: ArrayBuffer = await fontFile.arrayBuffer();
|
||||||
|
|
||||||
export const GET: RequestHandler = async () => {
|
export const GET: RequestHandler = async () => {
|
||||||
return await ImageResponse(template, {
|
return await ImageResponse(template, {
|
||||||
height: 630,
|
height: 630,
|
||||||
width: 1200,
|
width: 1200,
|
||||||
fonts: [
|
fonts: [
|
||||||
{
|
{
|
||||||
name: 'Inter Latin',
|
name: 'Inter Latin',
|
||||||
data: fontData,
|
data: fontData,
|
||||||
weight: 400
|
weight: 400
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
Then run `npm dev` and visit `localhost:5173/og` to view your generated PNG. Remember that hot module reloading does not work with server routes, so if you change your HTML or CSS, hard refresh the route to see changes.
|
Then run `npm dev` and visit `localhost:5173/og` to view your generated PNG. Remember that hot module reloading does not work with server routes, so if you change your HTML or CSS, hard refresh the route to see changes.
|
||||||
|
|
||||||
## Example Output
|
## Example Output
|
||||||
|
|
||||||
@@ -69,10 +70,9 @@ Then run `npm dev` and visit `localhost:5173/og` to view your generated PNG. Rem
|
|||||||
|
|
||||||
When run in development, image headers contain `cache-control: no-cache, no-store`. In production, image headers contain `'cache-control': 'public, immutable, no-transform, max-age=31536000'`, which caches the image for 1 year. In both cases, the `'content-type': 'image/png'` is used.
|
When run in development, image headers contain `cache-control: no-cache, no-store`. In production, image headers contain `'cache-control': 'public, immutable, no-transform, max-age=31536000'`, which caches the image for 1 year. In both cases, the `'content-type': 'image/png'` is used.
|
||||||
|
|
||||||
|
|
||||||
## Styling
|
## Styling
|
||||||
|
|
||||||
Notice that our example uses TailwindCSS classes (e.g. `tw="bg-gray-50"`). Alternatively, your HTML can contain style attributes using any of [the subset of CSS supported by Satori](https://github.com/vercel/satori#css).
|
Notice that our example uses TailwindCSS classes (e.g. `tw="bg-gray-50"`). Alternatively, your HTML can contain style attributes using any of [the subset of CSS supported by Satori](https://github.com/vercel/satori#css).
|
||||||
|
|
||||||
Satori supports only a subset of HTML and CSS. For full details, see [Satori’s documentation](https://github.com/vercel/satori#documentation). Notably, Satori only supports flex-based layouts.
|
Satori supports only a subset of HTML and CSS. For full details, see [Satori’s documentation](https://github.com/vercel/satori#documentation). Notably, Satori only supports flex-based layouts.
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ Satori supports only a subset of HTML and CSS. For full details, see [Satori’s
|
|||||||
|
|
||||||
Satori supports `ttf`, `otf`, and `woff` font formats; `woff2` is not supported. To maximize the font parsing speed, `ttf` or `otf` are recommended over `woff`.
|
Satori supports `ttf`, `otf`, and `woff` font formats; `woff2` is not supported. To maximize the font parsing speed, `ttf` or `otf` are recommended over `woff`.
|
||||||
|
|
||||||
By default, `@ethercorps/sveltekit-og` includes only 'Noto Sans' font. If you need to use other fonts, you can specify them as shown in the example. Notably, you can also import a font file that is stored locally within your project and are not required to use fetch.
|
By default, `@ethercorps/sveltekit-og` includes only 'Noto Sans' font. If you need to use other fonts, you can specify them as shown in the example. Notably, you can also import a font file that is stored locally within your project and are not required to use fetch.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ ImageResponse(
|
|||||||
options : {
|
options : {
|
||||||
width ? : number = 1200
|
width ? : number = 1200
|
||||||
height ? : number = 630,
|
height ? : number = 630,
|
||||||
backgroundColor ? : string = "#fff"
|
backgroundColor ? : string = "#fff"
|
||||||
fonts ? : {
|
fonts ? : {
|
||||||
name: string,
|
name: string,
|
||||||
data: ArrayBuffer,
|
data: ArrayBuffer,
|
||||||
@@ -142,6 +142,7 @@ componentToImageResponse(
|
|||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
### v1.2.3 Update (Breaking Changes)
|
### v1.2.3 Update (Breaking Changes)
|
||||||
|
|
||||||
> Now you have to install dependency by yourself which will make it easier to build for all plateforms.
|
> Now you have to install dependency by yourself which will make it easier to build for all plateforms.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
"svelte": "^3.59.1",
|
"svelte": "^3.59.1",
|
||||||
"vite": "^4.3.9",
|
"vite": "^4.3.9",
|
||||||
"url": "^0.11.0",
|
"url": "^0.11.0",
|
||||||
"//":"url package is required to work on cloudflare workers and pages."
|
"//": "url package is required to work on cloudflare workers and pages."
|
||||||
},
|
},
|
||||||
"type": "module"
|
"type": "module"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
"svelte": "^3.59.1",
|
"svelte": "^3.59.1",
|
||||||
"vite": "^4.3.9",
|
"vite": "^4.3.9",
|
||||||
"url": "^0.11.0",
|
"url": "^0.11.0",
|
||||||
"//":"url package is required to work on cloudflare workers and pages."
|
"//": "url package is required to work on cloudflare workers and pages."
|
||||||
},
|
},
|
||||||
"type": "module"
|
"type": "module"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,6 @@
|
|||||||
<div>%sveltekit.body%</div>
|
<div>%sveltekit.body%</div>
|
||||||
</body>
|
</body>
|
||||||
<script>
|
<script>
|
||||||
var global = global || window
|
var global = global || window;
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
"format": "prettier --plugin-search-dir . --write ."
|
"format": "prettier --plugin-search-dir . --write ."
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@playwright/test": "^1.34.3",
|
"@playwright/test": "^1.35.0",
|
||||||
"@sveltejs/adapter-auto": "next",
|
"@sveltejs/adapter-auto": "next",
|
||||||
"@sveltejs/adapter-vercel": "^2.4.3",
|
"@sveltejs/adapter-vercel": "^2.4.3",
|
||||||
"@sveltejs/kit": "1.10.0",
|
"@sveltejs/kit": "1.10.0",
|
||||||
@@ -30,6 +30,7 @@
|
|||||||
"postcss": "^8.4.24",
|
"postcss": "^8.4.24",
|
||||||
"prettier": "^2.8.8",
|
"prettier": "^2.8.8",
|
||||||
"prettier-plugin-svelte": "^2.10.1",
|
"prettier-plugin-svelte": "^2.10.1",
|
||||||
|
"prism-svelte": "^0.5.0",
|
||||||
"prismjs": "^1.29.0",
|
"prismjs": "^1.29.0",
|
||||||
"svelte": "^3.59.1",
|
"svelte": "^3.59.1",
|
||||||
"svelte-check": "^2.10.3",
|
"svelte-check": "^2.10.3",
|
||||||
|
|||||||
57
pnpm-lock.yaml
generated
57
pnpm-lock.yaml
generated
@@ -14,8 +14,8 @@ dependencies:
|
|||||||
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@playwright/test':
|
'@playwright/test':
|
||||||
specifier: ^1.34.3
|
specifier: ^1.35.0
|
||||||
version: 1.34.3
|
version: 1.35.0
|
||||||
'@sveltejs/adapter-auto':
|
'@sveltejs/adapter-auto':
|
||||||
specifier: next
|
specifier: next
|
||||||
version: 1.0.0-next.91(@sveltejs/kit@1.10.0)
|
version: 1.0.0-next.91(@sveltejs/kit@1.10.0)
|
||||||
@@ -58,6 +58,9 @@ devDependencies:
|
|||||||
prettier-plugin-svelte:
|
prettier-plugin-svelte:
|
||||||
specifier: ^2.10.1
|
specifier: ^2.10.1
|
||||||
version: 2.10.1(prettier@2.8.8)(svelte@3.59.1)
|
version: 2.10.1(prettier@2.8.8)(svelte@3.59.1)
|
||||||
|
prism-svelte:
|
||||||
|
specifier: ^0.5.0
|
||||||
|
version: 0.5.0
|
||||||
prismjs:
|
prismjs:
|
||||||
specifier: ^1.29.0
|
specifier: ^1.29.0
|
||||||
version: 1.29.0
|
version: 1.29.0
|
||||||
@@ -418,13 +421,13 @@ packages:
|
|||||||
fastq: 1.15.0
|
fastq: 1.15.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@playwright/test@1.34.3:
|
/@playwright/test@1.35.0:
|
||||||
resolution: {integrity: sha512-zPLef6w9P6T/iT6XDYG3mvGOqOyb6eHaV9XtkunYs0+OzxBtrPAAaHotc0X+PJ00WPPnLfFBTl7mf45Mn8DBmw==}
|
resolution: {integrity: sha512-6qXdd5edCBynOwsz1YcNfgX8tNWeuS9fxy5o59D0rvHXxRtjXRebB4gE4vFVfEMXl/z8zTnAzfOs7aQDEs8G4Q==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=16'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 20.2.5
|
'@types/node': 20.2.6
|
||||||
playwright-core: 1.34.3
|
playwright-core: 1.35.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.2
|
fsevents: 2.3.2
|
||||||
dev: true
|
dev: true
|
||||||
@@ -560,8 +563,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==}
|
resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@types/node@20.2.5:
|
/@types/node@20.2.6:
|
||||||
resolution: {integrity: sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==}
|
resolution: {integrity: sha512-GQBWUtGoefMEOx/vu+emHEHU5aw6JdDoEtZhoBrHFPZbA/YNRFfN996XbBASEWdvmLSLyv9FKYppYGyZjCaq/g==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@types/pug@2.0.6:
|
/@types/pug@2.0.6:
|
||||||
@@ -572,7 +575,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-jn7qwGFmJHwUSphV8zZneO3GmtlgLsmhs/LQyVvQbIIa+fzGMUiHI4HXJZL3FT8MJmgXWbLGiVVY7ElvHq6vDA==}
|
resolution: {integrity: sha512-jn7qwGFmJHwUSphV8zZneO3GmtlgLsmhs/LQyVvQbIIa+fzGMUiHI4HXJZL3FT8MJmgXWbLGiVVY7ElvHq6vDA==}
|
||||||
deprecated: This is a stub types definition. sass provides its own type definitions, so you do not need this installed.
|
deprecated: This is a stub types definition. sass provides its own type definitions, so you do not need this installed.
|
||||||
dependencies:
|
dependencies:
|
||||||
sass: 1.62.1
|
sass: 1.63.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@types/semver@7.5.0:
|
/@types/semver@7.5.0:
|
||||||
@@ -827,7 +830,7 @@ packages:
|
|||||||
postcss: ^8.1.0
|
postcss: ^8.1.0
|
||||||
dependencies:
|
dependencies:
|
||||||
browserslist: 4.21.7
|
browserslist: 4.21.7
|
||||||
caniuse-lite: 1.0.30001495
|
caniuse-lite: 1.0.30001498
|
||||||
fraction.js: 4.2.0
|
fraction.js: 4.2.0
|
||||||
normalize-range: 0.1.2
|
normalize-range: 0.1.2
|
||||||
picocolors: 1.0.0
|
picocolors: 1.0.0
|
||||||
@@ -878,8 +881,8 @@ packages:
|
|||||||
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
caniuse-lite: 1.0.30001495
|
caniuse-lite: 1.0.30001498
|
||||||
electron-to-chromium: 1.4.423
|
electron-to-chromium: 1.4.427
|
||||||
node-releases: 2.0.12
|
node-releases: 2.0.12
|
||||||
update-browserslist-db: 1.0.11(browserslist@4.21.7)
|
update-browserslist-db: 1.0.11(browserslist@4.21.7)
|
||||||
dev: true
|
dev: true
|
||||||
@@ -909,8 +912,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==}
|
resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/caniuse-lite@1.0.30001495:
|
/caniuse-lite@1.0.30001498:
|
||||||
resolution: {integrity: sha512-F6x5IEuigtUfU5ZMQK2jsy5JqUUlEFRVZq8bO2a+ysq5K7jD6PPc9YXZj78xDNS3uNchesp1Jw47YXEqr+Viyg==}
|
resolution: {integrity: sha512-LFInN2zAwx3ANrGCDZ5AKKJroHqNKyjXitdV5zRIVIaQlXKj3GmxUKagoKsjqUfckpAObPCEWnk5EeMlyMWcgw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/chalk@4.1.2:
|
/chalk@4.1.2:
|
||||||
@@ -1075,8 +1078,8 @@ packages:
|
|||||||
esutils: 2.0.3
|
esutils: 2.0.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/electron-to-chromium@1.4.423:
|
/electron-to-chromium@1.4.427:
|
||||||
resolution: {integrity: sha512-y4A7YfQcDGPAeSWM1IuoWzXpg9RY1nwHzHSwRtCSQFp9FgAVDgdWlFf0RbdWfLWQ2WUI+bddUgk5RgTjqRE6FQ==}
|
resolution: {integrity: sha512-HK3r9l+Jm8dYAm1ctXEWIC+hV60zfcjS9UA5BDlYvnI5S7PU/yytjpvSrTNrSSRRkuu3tDyZhdkwIczh+0DWaw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/emoji-regex@10.2.1:
|
/emoji-regex@10.2.1:
|
||||||
@@ -1930,9 +1933,9 @@ packages:
|
|||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/playwright-core@1.34.3:
|
/playwright-core@1.35.0:
|
||||||
resolution: {integrity: sha512-2pWd6G7OHKemc5x1r1rp8aQcpvDh7goMBZlJv6Co5vCNLVcQJdhxRL09SGaY6HcyHH9aT4tiynZabMofVasBYw==}
|
resolution: {integrity: sha512-muMXyPmIx/2DPrCHOD1H1ePT01o7OdKxKj2ebmCAYvqhUy+Y1bpal7B0rdoxros7YrXI294JT/DWw2LqyiqTPA==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=16'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
@@ -2026,6 +2029,10 @@ packages:
|
|||||||
hasBin: true
|
hasBin: true
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/prism-svelte@0.5.0:
|
||||||
|
resolution: {integrity: sha512-db91Bf3pRGKDPz1lAqLFSJXeW13mulUJxhycysFpfXV5MIK7RgWWK2E5aPAa71s8TCzQUXxF5JOV42/iOs6QkA==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/prismjs@1.29.0:
|
/prismjs@1.29.0:
|
||||||
resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==}
|
resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@@ -2100,8 +2107,8 @@ packages:
|
|||||||
glob: 7.2.3
|
glob: 7.2.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/rollup@3.24.0:
|
/rollup@3.24.1:
|
||||||
resolution: {integrity: sha512-OgraHOIg2YpHQTjl0/ymWfFNBEyPucB7lmhXrQUh38qNOegxLapSPFs9sNr0qKR75awW41D93XafoR2QfhBdUQ==}
|
resolution: {integrity: sha512-REHe5dx30ERBRFS0iENPHy+t6wtSEYkjrhwNsLyh3qpRaZ1+aylvMUdMBUHWUD/RjjLmLzEvY8Z9XRlpcdIkHA==}
|
||||||
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
|
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
@@ -2134,8 +2141,8 @@ packages:
|
|||||||
rimraf: 2.7.1
|
rimraf: 2.7.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/sass@1.62.1:
|
/sass@1.63.3:
|
||||||
resolution: {integrity: sha512-NHpxIzN29MXvWiuswfc1W3I0N8SXBd8UR26WntmDlRYf0bSADnwnOjsyMZ3lMezSlArD33Vs3YFhp7dWvL770A==}
|
resolution: {integrity: sha512-ySdXN+DVpfwq49jG1+hmtDslYqpS7SkOR5GpF6o2bmb1RL/xS+wvPmegMvMywyfsmAV6p7TgwXYGrCZIFFbAHg==}
|
||||||
engines: {node: '>=14.0.0'}
|
engines: {node: '>=14.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -2600,7 +2607,7 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
esbuild: 0.17.19
|
esbuild: 0.17.19
|
||||||
postcss: 8.4.24
|
postcss: 8.4.24
|
||||||
rollup: 3.24.0
|
rollup: 3.24.1
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.2
|
fsevents: 2.3.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|||||||
12
src/app.css
12
src/app.css
@@ -3,12 +3,12 @@
|
|||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Ian Mono';
|
font-family: 'Ian Mono';
|
||||||
src: url('/iaw-mono-var.woff2') format('woff2');
|
src: url('/iaw-mono-var.woff2') format('woff2');
|
||||||
}
|
}
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
html {
|
html {
|
||||||
font-family: Ian Mono, monospace;
|
font-family: Ian Mono, monospace;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,157 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import { createEventDispatcher, tick, onMount, onDestroy } from "svelte";
|
|
||||||
import * as ace from "brace";
|
|
||||||
import "brace/ext/emmet";
|
|
||||||
const EDITOR_ID = `svelte-ace-editor-div:${Math.floor(
|
|
||||||
Math.random() * 10000000000
|
|
||||||
)}`;
|
|
||||||
const dispatch = createEventDispatcher<{
|
|
||||||
init: ace.Editor;
|
|
||||||
input: string;
|
|
||||||
selectionChange: any;
|
|
||||||
blur: void;
|
|
||||||
changeMode: any;
|
|
||||||
commandKey: { err: any; hashId: any; keyCode: any };
|
|
||||||
copy: void;
|
|
||||||
cursorChange: void;
|
|
||||||
cut: void;
|
|
||||||
documentChange: { data: any };
|
|
||||||
focus: void;
|
|
||||||
paste: string;
|
|
||||||
}>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* translation of vue component to svelte:
|
|
||||||
* @link https://github.com/chairuosen/vue2-ace-editor/blob/91051422b36482eaf94271f1a263afa4b998f099/index.js
|
|
||||||
**/
|
|
||||||
export let value: string = ""; // String, required
|
|
||||||
export let lang: string = "json"; // String
|
|
||||||
export let theme: string = "chrome"; // String
|
|
||||||
export let height: string = "100%"; // null for 100, else integer, used as percent
|
|
||||||
export let width: string = "100%"; // null for 100, else integer, used as percent
|
|
||||||
export let options: any = {}; // Object
|
|
||||||
export let readonly: boolean = false;
|
|
||||||
|
|
||||||
let editor: ace.Editor;
|
|
||||||
let contentBackup: string = "";
|
|
||||||
|
|
||||||
const requireEditorPlugins = () => {};
|
|
||||||
requireEditorPlugins();
|
|
||||||
|
|
||||||
onDestroy(() => {
|
|
||||||
if (editor) {
|
|
||||||
editor.destroy();
|
|
||||||
editor.container.remove();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$: watchValue(value);
|
|
||||||
function watchValue(val: string) {
|
|
||||||
if (contentBackup !== val && editor && typeof val === "string") {
|
|
||||||
editor.session.setValue(val);
|
|
||||||
contentBackup = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$: watchTheme(theme);
|
|
||||||
function watchTheme(newTheme: string) {
|
|
||||||
if (editor) {
|
|
||||||
editor.setTheme("ace/theme/" + newTheme);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$: watchMode(lang);
|
|
||||||
function watchMode(newOption: any) {
|
|
||||||
if (editor) {
|
|
||||||
editor.getSession().setMode("ace/mode/" + newOption);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$: watchOptions(options);
|
|
||||||
function watchOptions(newOption: any) {
|
|
||||||
if (editor) {
|
|
||||||
editor.setOptions(newOption);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$: watchReadOnlyFlag(readonly);
|
|
||||||
function watchReadOnlyFlag(flag) {
|
|
||||||
if (editor) {
|
|
||||||
editor.setReadOnly(flag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const resizeOnNextTick = () =>
|
|
||||||
tick().then(() => {
|
|
||||||
if (editor) {
|
|
||||||
editor.resize();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$: if (height !== null && width !== null) {
|
|
||||||
resizeOnNextTick();
|
|
||||||
}
|
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
lang = lang || "text";
|
|
||||||
theme = theme || "chrome";
|
|
||||||
|
|
||||||
editor = ace.edit(EDITOR_ID);
|
|
||||||
|
|
||||||
dispatch("init", editor);
|
|
||||||
editor.$blockScrolling = Infinity;
|
|
||||||
// editor.setOption("enableEmmet", true);
|
|
||||||
editor.getSession().setMode("ace/mode/" + lang);
|
|
||||||
editor.setTheme("ace/theme/" + theme);
|
|
||||||
editor.setValue(value, 1);
|
|
||||||
editor.setReadOnly(readonly)
|
|
||||||
contentBackup = value;
|
|
||||||
setEventCallBacks();
|
|
||||||
if (options) {
|
|
||||||
editor.setOptions(options);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const ValidPxDigitsRegEx = /^\d*$/;
|
|
||||||
function px(n: string): string {
|
|
||||||
if (ValidPxDigitsRegEx.test(n)) {
|
|
||||||
return n + "px";
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
function setEventCallBacks() {
|
|
||||||
editor.onBlur = () => dispatch("blur");
|
|
||||||
editor.onChangeMode = (obj) => dispatch("changeMode", obj);
|
|
||||||
editor.onCommandKey = (err, hashId, keyCode) =>
|
|
||||||
dispatch("commandKey", { err, hashId, keyCode });
|
|
||||||
editor.onCopy = () => dispatch("copy");
|
|
||||||
editor.onCursorChange = () => dispatch("cursorChange");
|
|
||||||
editor.onCut = () => {
|
|
||||||
const copyText = editor.getCopyText();
|
|
||||||
console.log("cut event : ", copyText);
|
|
||||||
editor.insert("");
|
|
||||||
dispatch("cut");
|
|
||||||
};
|
|
||||||
editor.onDocumentChange = (obj: { data: any }) =>
|
|
||||||
dispatch("documentChange", obj);
|
|
||||||
editor.onFocus = () => dispatch("focus");
|
|
||||||
editor.onPaste = (text) => {
|
|
||||||
console.log("paste event : ", text);
|
|
||||||
editor.insert(text);
|
|
||||||
dispatch("paste", text);
|
|
||||||
};
|
|
||||||
editor.onSelectionChange = (obj) => dispatch("selectionChange", obj);
|
|
||||||
editor.on("change", function () {
|
|
||||||
const content = editor.getValue();
|
|
||||||
value = content;
|
|
||||||
dispatch("input", content);
|
|
||||||
contentBackup = content;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div style="width:{px(width)};">
|
|
||||||
<h1 class="font-bold mb-2">Editor</h1>
|
|
||||||
<div id={EDITOR_ID} style="width:{px(width)};" class="h-[80vh] rounded rounded-lg border border-gray-500"/>
|
|
||||||
</div>
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
let menuBar = false
|
let menuBar = false;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- navbar goes here -->
|
<!-- navbar goes here -->
|
||||||
@@ -9,28 +9,42 @@
|
|||||||
<div class="flex space-x-4">
|
<div class="flex space-x-4">
|
||||||
<!-- logo -->
|
<!-- logo -->
|
||||||
<div>
|
<div>
|
||||||
<a href="#" class="flex items-center py-5 px-2 space-x-1 text-gray-700 hover:text-gray-900">
|
<a
|
||||||
<svg
|
href="#"
|
||||||
viewBox="0 0 75 65"
|
class="flex items-center py-5 px-2 text-gray-700 hover:text-gray-900 space-x-3"
|
||||||
fill="black"
|
>
|
||||||
class="w-4 h-4 rotate-90"
|
<svg viewBox="0 0 75 65" fill="black" class="w-4 h-4 rotate-90">
|
||||||
>
|
<path d="M37.59.25l36.95 64H.64l36.95-64z" />
|
||||||
<path d="M37.59.25l36.95 64H.64l36.95-64z"></path>
|
|
||||||
</svg>
|
</svg>
|
||||||
<span class="font-bold">Sveltekit-OG Playground</span>
|
<span class="font-bold">Sveltekit-OG</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- secondary nav -->
|
<!-- secondary nav -->
|
||||||
<div class="hidden md:flex items-center space-x-1">
|
<div class="hidden md:flex items-center space-x-1">
|
||||||
<a href="https://github.com/etherCorps/sveltekit-og/#readme" target="_blank" rel="noreferrer" class="py-5 px-3 underline">Docs</a>
|
<a
|
||||||
<a href="https://github.com/etherCorps/sveltekit-og" target="_blank" rel="noreferrer" class="py-5 px-3 underline">Github</a>
|
href="https://github.com/etherCorps/sveltekit-og/#readme"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
class="py-5 px-3 underline">Docs</a
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
href="https://github.com/etherCorps/sveltekit-og"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
class="py-5 px-3 underline">Github</a
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- mobile button goes here -->
|
<!-- mobile button goes here -->
|
||||||
<div class="md:hidden flex items-center">
|
<div class="md:hidden flex items-center">
|
||||||
<button class="mobile-menu-button" on:click={() => {menuBar = !menuBar}}>
|
<button
|
||||||
|
class="mobile-menu-button"
|
||||||
|
on:click={() => {
|
||||||
|
menuBar = !menuBar;
|
||||||
|
}}
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
class="w-6 h-6"
|
class="w-6 h-6"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@@ -51,7 +65,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- mobile menu -->
|
<!-- mobile menu -->
|
||||||
<div class="mobile-menu {menuBar ? '': 'hidden'} md:hidden">
|
<div class="mobile-menu {menuBar ? '' : 'hidden'} md:hidden">
|
||||||
<a href="#" class="block py-2 px-4 text-sm hover:bg-gray-200">Docs</a>
|
<a href="#" class="block py-2 px-4 text-sm hover:bg-gray-200">Docs</a>
|
||||||
<a href="#" class="block py-2 px-4 text-sm hover:bg-gray-200">Github</a>
|
<a href="#" class="block py-2 px-4 text-sm hover:bg-gray-200">Github</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -34,16 +34,16 @@ const ImageResponse = async (htmlTemplate: string, optionsByUser: ImageResponseO
|
|||||||
|
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
await initSvgToPng();
|
await initSvgToPng();
|
||||||
initialized = true
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultConfig: ConvertOptions = {
|
const defaultConfig: ConvertOptions = {
|
||||||
width: options.width, // optional
|
width: options.width, // optional
|
||||||
height: options.height, // optional
|
height: options.height // optional
|
||||||
};
|
};
|
||||||
|
|
||||||
if (Object.hasOwn(options, 'backgroundColor')) {
|
if (Object.hasOwn(options, 'backgroundColor')) {
|
||||||
defaultConfig.backgroundColor = options.backgroundColor
|
defaultConfig.backgroundColor = options.backgroundColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
const png = await svg2png(svg, defaultConfig);
|
const png = await svg2png(svg, defaultConfig);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<script>
|
<script>
|
||||||
import '../app.css';
|
import '../app.css';
|
||||||
import Navbar from "../components/Navbar.svelte";
|
import Navbar from '../components/Navbar.svelte';
|
||||||
</script>
|
</script>
|
||||||
<div class="max-h-screen">
|
|
||||||
<Navbar/>
|
|
||||||
<slot />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<div class="max-h-screen">
|
||||||
|
<Navbar />
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -1,40 +1,129 @@
|
|||||||
<script lang="ts">
|
<script>
|
||||||
import AceEditor from "/src/components/AceEditor.svelte";
|
import {base} from "$app/paths";
|
||||||
import "brace/mode/html";
|
import Prism from 'prismjs';
|
||||||
import "brace/theme/chrome";
|
import 'prism-svelte';
|
||||||
let text = "<h1>hii</h1>";
|
import 'prismjs/themes/prism-tomorrow.css';
|
||||||
</script>
|
const source = `
|
||||||
|
/src/routes/new/+server.ts
|
||||||
|
|
||||||
<div class="grid grid-cols-2 space-x-10 p-10">
|
import { ImageResponse } from '@ethercorps/sveltekit-og';
|
||||||
<AceEditor style="border: solid"
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
on:selectionChange={(obj) => console.log(obj.detail)}
|
|
||||||
on:paste={(obj) => console.log(obj.detail)}
|
const template = \`
|
||||||
on:input={(obj) => console.log(obj.detail)}
|
<div tw="bg-gray-50 flex w-full h-full items-center justify-center">
|
||||||
on:focus={() => console.log('focus')}
|
<div tw="flex flex-col md:flex-row w-full py-12 px-4 md:items-center justify-between p-8">
|
||||||
on:documentChange={(obj) => console.log(`document change : ${obj.detail}`)}
|
<h2 tw="flex flex-col text-3xl sm:text-4xl font-bold tracking-tight text-gray-900 text-left">
|
||||||
on:cut={() => console.log('cut')}
|
<span>Ready to dive in?</span>
|
||||||
on:cursorChange={() => console.log('cursor change')}
|
<span tw="text-indigo-600">Start your free trial today.</span>
|
||||||
on:copy={() => console.log('copy')}
|
</h2>
|
||||||
on:init={(editor) => console.log(editor.detail)}
|
<div tw="mt-8 flex md:mt-0">
|
||||||
on:commandKey={(obj) => console.log(obj.detail)}
|
<div tw="flex rounded-md shadow">
|
||||||
on:changeMode={(obj) => console.log(`change mode : ${obj.detail}`)}
|
<a href="#" tw="flex items-center justify-center rounded-md border border-transparent bg-indigo-600 px-5 py-3 text-base font-medium text-white">Get started</a>
|
||||||
on:blur={() => console.log('blur')}
|
</div>
|
||||||
lang="html"
|
<div tw="ml-3 flex rounded-md shadow">
|
||||||
theme="chrome"
|
<a href="#" tw="flex items-center justify-center rounded-md border border-transparent bg-white px-5 py-3 text-base font-medium text-indigo-600">Learn more</a>
|
||||||
value={text}
|
</div>
|
||||||
/>
|
</div>
|
||||||
<div class="grid grid-rows-2 mt-8 space-y-4">
|
|
||||||
<div class="common">
|
|
||||||
Editor Under Development
|
|
||||||
</div>
|
|
||||||
<div class="common">
|
|
||||||
Coming Soon...
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
\`;
|
||||||
|
|
||||||
<style>
|
const fontFile400 = await fetch(
|
||||||
.common {
|
'https://raw.githubusercontent.com/etherCorps/sveltekit-og/main/static/inter-latin-ext-400-normal.woff'
|
||||||
@apply border border-gray-800 rounded p-5
|
);
|
||||||
}
|
|
||||||
</style>
|
const fontFile700 = await fetch(
|
||||||
|
'https://raw.githubusercontent.com/etherCorps/sveltekit-og/main/static/inter-latin-ext-700-normal.woff'
|
||||||
|
);
|
||||||
|
|
||||||
|
const fontData400: ArrayBuffer = await fontFile400.arrayBuffer();
|
||||||
|
const fontData700: ArrayBuffer = await fontFile700.arrayBuffer();
|
||||||
|
|
||||||
|
export const GET: RequestHandler = async () => {
|
||||||
|
return await ImageResponse(template, {
|
||||||
|
height: 250,
|
||||||
|
width: 500,
|
||||||
|
fonts: [
|
||||||
|
{
|
||||||
|
name: 'Inter Latin',
|
||||||
|
data: fontData400,
|
||||||
|
weight: 400
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Inter Latin',
|
||||||
|
data: fontData700,
|
||||||
|
weight: 700
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
`;
|
||||||
|
const highlightedQuickEg = Prism.highlight(source, Prism.languages.svelte, 'svelte');
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="mx-10 mt-5 space-y-5">
|
||||||
|
<section id="introduction" class="space-y-3">
|
||||||
|
<h1 class="font-bold text-2xl">Introduction</h1>
|
||||||
|
<p class="">
|
||||||
|
SvelteKit-OG is use to dynamically generate Open Graph images from an HTML+CSS template or
|
||||||
|
Svelte component using fast and efficient conversion from <br /> HTML > SVG > PNG. Based on Satori.
|
||||||
|
No headless browser required.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="installation" class="space-y-4">
|
||||||
|
<h1 class="font-bold text-2xl">Installation</h1>
|
||||||
|
<p>
|
||||||
|
Use your favourite package manager and add <span class="bg-gray-100 px-2 py-1 rounded-full"
|
||||||
|
>@ethercorps/sveltekit-og</span
|
||||||
|
>
|
||||||
|
as your <span class="bg-gray-100 px-2 py-1 rounded-full">devDependency</span>.
|
||||||
|
</p>
|
||||||
|
<div id="pnpm-install-og">
|
||||||
|
Example:
|
||||||
|
<code class="border rounded-full bg-gray-100 px-3 py-1.5 text-gray-900">
|
||||||
|
pnpm i -D @ethercorps/sveltekit-og
|
||||||
|
</code>
|
||||||
|
</div>
|
||||||
|
<div class="border-x-4 border-gray-900 rounded-lg leading-9">
|
||||||
|
<p class="ml-2">
|
||||||
|
If you are using it on with <span class="bg-gray-100 px-2 py-1 rounded-full">
|
||||||
|
cloudflare pages
|
||||||
|
</span>
|
||||||
|
or <span class="bg-gray-100 px-2 py-1 rounded-full">cloudflare workers </span> then you have
|
||||||
|
to provide <span class="bg-gray-100 px-2 py-1 rounded-full">polyfills</span> for
|
||||||
|
<span class="bg-gray-100 px-2 py-1 rounded-full">url</span>. You can simply add it to your
|
||||||
|
<span class="bg-gray-100 px-2 py-1 rounded-full">devDependency</span>,
|
||||||
|
<br /> To install
|
||||||
|
<code class="border rounded-full bg-gray-100 px-3 py-1.5 text-gray-900">
|
||||||
|
pnpm i -D url
|
||||||
|
</code>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section id="usage" class="space-y-3">
|
||||||
|
<h1 class="font-bold text-2xl">Usage</h1>
|
||||||
|
<p class="">
|
||||||
|
Create a file at <span class="bg-gray-100 px-2 py-1 rounded-full">
|
||||||
|
/src/routes/og/+server.ts
|
||||||
|
</span>. Alternatively, you can use JavaScript by removing the types from this example.
|
||||||
|
</p>
|
||||||
|
<div class="border-x-4 border-gray-900 rounded-lg w-fit px-2 leading-9">
|
||||||
|
<p class="ml-2">
|
||||||
|
Route can be anything but it should have only one file
|
||||||
|
<span class="bg-gray-100 px-2 py-1 rounded-full"> +server.ts </span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<pre class="bg-gray-100 overflow-auto px-3 py-1.5 rounded-xl"><code class="" >{@html highlightedQuickEg}</code></pre>
|
||||||
|
<div class="border-x-4 border-gray-900 rounded-lg w-fit px-2 leading-9">
|
||||||
|
<p class="ml-2">
|
||||||
|
Then run <span class="bg-gray-100 px-2 py-1 rounded-full"> pnpm run dev </span> and visit <span class="bg-gray-100 px-2 py-1 rounded-full"> localhost:5173/og </span> to view your generated PNG. Remember that hot module reloading does not work with server routes, so if you change your HTML or CSS, hard refresh the route to see changes.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<h2 class="font-bold text-xl">
|
||||||
|
Image Output: <a target="_blank" rel="noreferrer" href="https://sveltekit-og.ethercorps.io/new"> Live </a>
|
||||||
|
</h2>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -1 +1,13 @@
|
|||||||
export const ssr = false;
|
export const ssr = false;
|
||||||
|
|
||||||
|
const quickUseFile = import.meta.glob(['./new/+server.ts'], {as: 'raw'});
|
||||||
|
|
||||||
|
export const load = async () => {
|
||||||
|
const module = Object.entries(quickUseFile).map(([k, v]) =>
|
||||||
|
v().then((result) => {
|
||||||
|
const segments = k.split('/');
|
||||||
|
return { filename: segments.slice(2).join('/'), source: result };
|
||||||
|
}));
|
||||||
|
const code = Promise.all(module);
|
||||||
|
return {code}
|
||||||
|
};
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ import OG from './OG.svelte';
|
|||||||
import { componentToImageResponse } from '$lib';
|
import { componentToImageResponse } from '$lib';
|
||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
|
|
||||||
const fontFile = await fetch('https://raw.githubusercontent.com/etherCorps/sveltekit-og/main/static/inter-latin-ext-700-normal.woff');
|
const fontFile = await fetch(
|
||||||
|
'https://raw.githubusercontent.com/etherCorps/sveltekit-og/main/static/inter-latin-ext-700-normal.woff'
|
||||||
|
);
|
||||||
const fontData: ArrayBuffer = await fontFile.arrayBuffer();
|
const fontData: ArrayBuffer = await fontFile.arrayBuffer();
|
||||||
|
|
||||||
export const GET: RequestHandler = async () => {
|
export const GET: RequestHandler = async () => {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
`/src/routes/new/+server.ts`
|
||||||
|
|
||||||
import { ImageResponse } from '$lib';
|
import { ImageResponse } from '$lib';
|
||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
|
|
||||||
@@ -19,8 +21,12 @@ const template = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
const fontFile400 = await fetch('https://raw.githubusercontent.com/etherCorps/sveltekit-og/main/static/inter-latin-ext-400-normal.woff');
|
const fontFile400 = await fetch(
|
||||||
const fontFile700 = await fetch('https://raw.githubusercontent.com/etherCorps/sveltekit-og/main/static/inter-latin-ext-700-normal.woff');
|
'https://raw.githubusercontent.com/etherCorps/sveltekit-og/main/static/inter-latin-ext-400-normal.woff'
|
||||||
|
);
|
||||||
|
const fontFile700 = await fetch(
|
||||||
|
'https://raw.githubusercontent.com/etherCorps/sveltekit-og/main/static/inter-latin-ext-700-normal.woff'
|
||||||
|
);
|
||||||
const fontData400: ArrayBuffer = await fontFile400.arrayBuffer();
|
const fontData400: ArrayBuffer = await fontFile400.arrayBuffer();
|
||||||
const fontData700: ArrayBuffer = await fontFile700.arrayBuffer();
|
const fontData700: ArrayBuffer = await fontFile700.arrayBuffer();
|
||||||
|
|
||||||
|
|||||||
3
static/logo.svg
Normal file
3
static/logo.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg viewBox="0 0 75 65" fill="black" class="w-4 h-4 rotate-90">
|
||||||
|
<path d="M37.59.25l36.95 64H.64l36.95-64z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 122 B |
@@ -8,13 +8,11 @@ const config: UserConfig = {
|
|||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
external: ["@resvg/resvg-js"]
|
external: ['@resvg/resvg-js']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
exclude: [
|
exclude: ['@resvg/resvg-js']
|
||||||
"@resvg/resvg-js"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user