Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing Svelte 5 support #8

Open
socketopp opened this issue May 31, 2024 · 5 comments
Open

Missing Svelte 5 support #8

socketopp opened this issue May 31, 2024 · 5 comments
Assignees

Comments

@socketopp
Copy link

socketopp commented May 31, 2024

Invite.svelte

<script>
	import { Button, Hr, Html, Text, Head } from 'svelte-email-tailwind';

	export let name = 'World';
</script>

<Html lang="en">
	<Head />
	<Text class="md:text-[18px] text-[24px]">
		Hello, {name}!
	</Text>
	<Hr />
	<Button href="https://svelte.dev">Visit Svelte</Button>
</Html>


I have been using it like this

import { render as svelteRender } from 'svelte/server';
import type { SvelteComponent } from 'svelte';
import InviteTemplate from '$lib/emails/Invite.svelte';

export async function sendSvelteEmail({ from, to, subject, svelteEmail: { props, template } }) {
	type InviteProps = {
		name: string;
	};

	const componentProps: InviteProps = {
		name: 'Steven3'
	};

	const { html } = svelteRender(InviteTemplate as unknown as typeof SvelteComponent, { props: componentProps });
	....

However, I receive the following error in Svelte 5. Is there anything I can do to fix this?

Error: Missing <Head /> component!
    at substituteHead (file:/node_modules/svelte-email-tailwind/vite/utils/inline-tailwind.js:139:15)
    at inlineTailwind (file:/node_modules/svelte-email-tailwind/vite/utils/inline-tailwind.js:17:25)
    at TransformContext.transform (file:/node_modules/svelte-email-tailwind/vite/index.js:8:30)
    at Object.transform (file:/node_modules/vite/dist/node/chunks/dep-cNe07EU9.js:51139:62)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async loadAndTransform (file:/node_modules/vite/dist/node/chunks/dep-cNe07EU9.js:53894:29)
    at async instantiateModule (file:/node_modules/vite/dist/node/chunks/dep-cNe07EU9.js:54954:10) {
  plugin: 'vite:inline-tw',

Also the config require parameters


const emailTwConfig: TailwindConfig = {};
...
svelteEmailTailwind({ pathToEmailFolder: '/src/lib/emails', tailwindConfig: emailTwConfig })


Expected 1 arguments, but got 0.ts(2554)
index.d.ts(2, 45): An argument matching this binding pattern was not provided.
(alias) svelteEmailTailwind({ tailwindConfig, pathToEmailFolder }: {
    tailwindConfig?: TailwindConfig | undefined;
    pathToEmailFolder?: string | undefined;
}): {
    name: string;
    transform(src: string, id: string): Promise<{
        code: string;
    } | undefined>;
}
import svelteEmailTailwind

@steveninety
Copy link
Owner

I haven't looked into the Svelte 5 generated server JS output, but I suspect it has breaking changes.
So that would make this plugin incompatible with Svelte 5. I will look into making it compatible. I'm afraid there will be a lot that needs changing!

@steveninety steveninety self-assigned this May 31, 2024
@socketopp
Copy link
Author

socketopp commented May 31, 2024

I haven't looked into the Svelte 5 generated server JS output, but I suspect it has breaking changes. So that would make this plugin incompatible with Svelte 5. I will look into making it compatible. I'm afraid there will be a lot that needs changing!

What parts in svelte-email-tailwind is related to the breaking changes in Svelte 5?
I helped svelty-email with some breaking changes and it was only concerning Server API changes.

The error originates from:

function substituteHead(code, twClean) {
    // 3. Handle responsive head styles
    const headStyle = `<style>${getMediaQueryCss(twClean)}</style>`;
    // const hasResponsiveStyles = /@media[^{]+\{(?<content>[\s\S]+?)\}\s*\}/gm.test(headStyle)
    const startStringPre = '${validate_component(Head, "Head").$$render($$result,';
    const iS = code.indexOf(startStringPre);
    if (iS === -1) {
        throw new Error('Missing <Head /> component!');
    }

I am not sure why this error occurs or what the code is doing. The inline-tailwind.jsfile is quite complex. I couldn't imagine adding tailwind to svelte-email would be this complicated?

@steveninety
Copy link
Owner

steveninety commented Jun 1, 2024

What parts in svelte-email-tailwind is related to the breaking changes in Svelte 5?

This Vite plugin takes an email component's SSR code as a string, and manipulates the string. It looks for all 'class' properties, transforms those classes to styles, then put them back into the original stringified SSR code as a 'style' prop.

In Svelte 4, it would look something like this:
${validate_component(MyComponent, "MyComponent").$$render($$result, { classes: "text-sm" }, {}, {})}
This plugin then looks for the pattern $$result, {, and subsequently looks for class properties. It's turned into:
${validate_component(MyComponent, "MyComponent").$$render($$result, { style: "font-size: 14px" }, {}, {})}

In Svelte 5, the SSR JS output is different:
MyComponent($$payload, { classes: "text-sm" });

If we're lucky, the only syntax change is that '$$result' becomes '$$payload'. But I doubt that's all - I have to look into it.

PS: You can find these outputs on the Svelte REPL: in the JS "Output tab", with "Compiler options - generate" set to "SSR".

@socketopp
Copy link
Author

Interesting approach! Hope your migration to Svelte 5 goes well.

@0x0m0t0
Copy link

0x0m0t0 commented Jul 8, 2024

I'd love Svelte 5 support!

@steveninety steveninety changed the title Error: Missing <Head /> component! at substituteHead Missing Svelte 5 support Jul 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants