mirror of
https://github.com/LukeHagar/sveltekit-og.git
synced 2025-12-06 12:47:49 +00:00
Satori Issue
This commit is contained in:
@@ -4,13 +4,14 @@ About
|
|||||||
Generate Open Graph Images dynamically from HTML/CSS without a browser in SvelteKit.
|
Generate Open Graph Images dynamically from HTML/CSS without a browser in SvelteKit.
|
||||||
|
|
||||||
## v1.0.0 Update (Breaking Changes)
|
## v1.0.0 Update (Breaking Changes)
|
||||||
|
|
||||||
Finally, We have added html to react like element like object converter out of the box and with svelte compiler.
|
Finally, We have added html to react like element like object converter out of the box and with svelte compiler.
|
||||||
Now you can use `{ toReactElement }` with `"@ethercorps/sveltekit-og"` like:
|
Now you can use `{ toReactElement }` with `"@ethercorps/sveltekit-og"` like:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// +page.server.js
|
// +page.server.js
|
||||||
|
|
||||||
import { toReactElement, satori } from "@ethercorps/sveltekit-og"
|
import { toReactElement, satori } from '@ethercorps/sveltekit-og';
|
||||||
|
|
||||||
const htmlString = `
|
const htmlString = `
|
||||||
<div tw="bg-gray-50 flex w-full">
|
<div tw="bg-gray-50 flex w-full">
|
||||||
@@ -58,8 +59,7 @@ export async function load() {
|
|||||||
- We have changed to function based instead of class based ImageResponse and componentToImageResponse.
|
- We have changed to function based instead of class based ImageResponse and componentToImageResponse.
|
||||||
- Removed `@resvg/resvg-wasm` with `@resvg/resvg-js` because of internal errors.
|
- Removed `@resvg/resvg-wasm` with `@resvg/resvg-js` because of internal errors.
|
||||||
- Removed `satori-html` because now we have `toReactElement` out of the box with svelte compiler.
|
- Removed `satori-html` because now we have `toReactElement` out of the box with svelte compiler.
|
||||||
- Access to `satori` directly from `"@ethercorps/sveltekit-og"`. [_source_](/src/routes/test/+page.server.js) · [_demo_](https://sveltekit-og-five.vercel.app/test)
|
> If you find a problem related to undefined a please check [_vite.config.js_](/vite.config.ts) and add ` define: { _a: 'undefined' } in config.`
|
||||||
> If you find a problem related to undefined a please check [_vite.config.js_](/vite.config.ts) and add ``` define: { _a: 'undefined' } in config.```
|
|
||||||
|
|
||||||
> If you find any issue and have suggestion for this project please open a ticket and if you want to contribute please create a new discussion.
|
> If you find any issue and have suggestion for this project please open a ticket and if you want to contribute please create a new discussion.
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ImageResponse } from '@ethercorps/sveltekit-og';
|
import { ImageResponse } from '@ethercorps/sveltekit-og';
|
||||||
import type { RequestHandler } from "@sveltejs/kit";
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
|
|
||||||
const template = `
|
const template = `
|
||||||
<div tw="bg-gray-50 flex w-full h-full items-center justify-center">
|
<div tw="bg-gray-50 flex w-full h-full items-center justify-center">
|
||||||
|
|||||||
14
package.json
14
package.json
@@ -3,7 +3,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"private": false,
|
"private": false,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite dev",
|
"dev": "vite dev --host",
|
||||||
"build:prod": "vite build",
|
"build:prod": "vite build",
|
||||||
"build": "svelte-kit sync && svelte-package",
|
"build": "svelte-kit sync && svelte-package",
|
||||||
"prepublishOnly": "echo 'Did you mean to publish `./package/`, instead of `./`?' && exit 1",
|
"prepublishOnly": "echo 'Did you mean to publish `./package/`, instead of `./`?' && exit 1",
|
||||||
@@ -16,21 +16,27 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@playwright/test": "^1.28.1",
|
"@playwright/test": "^1.28.1",
|
||||||
"@sveltejs/adapter-auto": "next",
|
"@sveltejs/adapter-auto": "next",
|
||||||
"@sveltejs/kit": "next",
|
"@sveltejs/kit": "1.0.0-next.581",
|
||||||
"@sveltejs/package": "next",
|
"@sveltejs/package": "next",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.46.0",
|
"@typescript-eslint/eslint-plugin": "^5.46.0",
|
||||||
"@typescript-eslint/parser": "^5.46.0",
|
"@typescript-eslint/parser": "^5.46.0",
|
||||||
|
"autoprefixer": "^10.4.13",
|
||||||
|
"brace": "^0.11.1",
|
||||||
"eslint": "^8.29.0",
|
"eslint": "^8.29.0",
|
||||||
"eslint-config-prettier": "^8.5.0",
|
"eslint-config-prettier": "^8.5.0",
|
||||||
"eslint-plugin-svelte3": "^4.0.0",
|
"eslint-plugin-svelte3": "^4.0.0",
|
||||||
|
"monaco-editor": "^0.34.1",
|
||||||
|
"postcss": "^8.4.19",
|
||||||
"prettier": "^2.8.1",
|
"prettier": "^2.8.1",
|
||||||
"prettier-plugin-svelte": "^2.8.1",
|
"prettier-plugin-svelte": "^2.9.0",
|
||||||
|
"prismjs": "^1.29.0",
|
||||||
"svelte": "^3.54.0",
|
"svelte": "^3.54.0",
|
||||||
"svelte-check": "^2.10.2",
|
"svelte-check": "^2.10.2",
|
||||||
"svelte-preprocess": "^4.10.7",
|
"svelte-preprocess": "^4.10.7",
|
||||||
|
"tailwindcss": "^3.2.4",
|
||||||
"tslib": "^2.4.1",
|
"tslib": "^2.4.1",
|
||||||
"typescript": "^4.9.4",
|
"typescript": "^4.9.4",
|
||||||
"vite": "^3.2.5"
|
"vite": "^4.0.0"
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
797
pnpm-lock.yaml
generated
797
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
6
postcss.config.cjs
Normal file
6
postcss.config.cjs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {}
|
||||||
|
}
|
||||||
|
};
|
||||||
14
src/app.css
Normal file
14
src/app.css
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Ian Mono';
|
||||||
|
src: url('/iaw-mono-var.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
html {
|
||||||
|
font-family: Ian Mono, monospace;
|
||||||
|
}
|
||||||
|
}
|
||||||
157
src/components/AceEditor.svelte
Normal file
157
src/components/AceEditor.svelte
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
<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>
|
||||||
58
src/components/Navbar.svelte
Normal file
58
src/components/Navbar.svelte
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<script>
|
||||||
|
let menuBar = false
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- navbar goes here -->
|
||||||
|
<nav class="bg-gray-100">
|
||||||
|
<div class="max-w-full mx-auto px-4">
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<div class="flex space-x-4">
|
||||||
|
<!-- logo -->
|
||||||
|
<div>
|
||||||
|
<a href="#" class="flex items-center py-5 px-2 space-x-1 text-gray-700 hover:text-gray-900">
|
||||||
|
<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>
|
||||||
|
</svg>
|
||||||
|
<span class="font-bold">Sveltekit-OG Playground</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- secondary nav -->
|
||||||
|
<div class="hidden md:flex items-center space-x-1">
|
||||||
|
<a href="" class="py-5 px-3 underline">Docs</a>
|
||||||
|
<a href="" class="py-5 px-3 underline">Github</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- mobile button goes here -->
|
||||||
|
<div class="md:hidden flex items-center">
|
||||||
|
<button class="mobile-menu-button" on:click={() => {menuBar = !menuBar}}>
|
||||||
|
<svg
|
||||||
|
class="w-6 h-6"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M4 6h16M4 12h16M4 18h16"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- mobile menu -->
|
||||||
|
<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">Github</a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
9
src/routes/+layout.svelte
Normal file
9
src/routes/+layout.svelte
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<script>
|
||||||
|
import '../app.css';
|
||||||
|
import Navbar from "../components/Navbar.svelte";
|
||||||
|
</script>
|
||||||
|
<div class="max-h-screen">
|
||||||
|
<Navbar/>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import AceEditor from "/src/components/AceEditor.svelte";
|
||||||
|
import "brace/mode/html";
|
||||||
|
import "brace/theme/chrome";
|
||||||
|
let text = "<h1>hii</h1>";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-2 space-x-10 p-10">
|
||||||
|
<AceEditor style="border: solid"
|
||||||
|
on:selectionChange={(obj) => console.log(obj.detail)}
|
||||||
|
on:paste={(obj) => console.log(obj.detail)}
|
||||||
|
on:input={(obj) => console.log(obj.detail)}
|
||||||
|
on:focus={() => console.log('focus')}
|
||||||
|
on:documentChange={(obj) => console.log(`document change : ${obj.detail}`)}
|
||||||
|
on:cut={() => console.log('cut')}
|
||||||
|
on:cursorChange={() => console.log('cursor change')}
|
||||||
|
on:copy={() => console.log('copy')}
|
||||||
|
on:init={(editor) => console.log(editor.detail)}
|
||||||
|
on:commandKey={(obj) => console.log(obj.detail)}
|
||||||
|
on:changeMode={(obj) => console.log(`change mode : ${obj.detail}`)}
|
||||||
|
on:blur={() => console.log('blur')}
|
||||||
|
lang="html"
|
||||||
|
theme="chrome"
|
||||||
|
value={text}
|
||||||
|
/>
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.common {
|
||||||
|
@apply border border-gray-800 rounded p-5
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
BIN
static/iaw-mono-var.woff2
Normal file
BIN
static/iaw-mono-var.woff2
Normal file
Binary file not shown.
@@ -5,8 +5,11 @@ import preprocess from 'svelte-preprocess';
|
|||||||
const config = {
|
const config = {
|
||||||
// Consult https://github.com/sveltejs/svelte-preprocess
|
// Consult https://github.com/sveltejs/svelte-preprocess
|
||||||
// for more information about preprocessors
|
// for more information about preprocessors
|
||||||
preprocess: preprocess(),
|
preprocess: [
|
||||||
|
preprocess({
|
||||||
|
postcss: true
|
||||||
|
})
|
||||||
|
],
|
||||||
kit: {
|
kit: {
|
||||||
adapter: adapter()
|
adapter: adapter()
|
||||||
}
|
}
|
||||||
|
|||||||
8
tailwind.config.cjs
Normal file
8
tailwind.config.cjs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
module.exports = {
|
||||||
|
content: ['./src/**/*.{html,js,svelte,ts}'],
|
||||||
|
theme: {
|
||||||
|
extend: {}
|
||||||
|
},
|
||||||
|
plugins: []
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user