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

SvelteKit #50

Closed
carstenjaksch opened this issue Mar 10, 2024 · 8 comments
Closed

SvelteKit #50

carstenjaksch opened this issue Mar 10, 2024 · 8 comments

Comments

@carstenjaksch
Copy link

I have a hard time getting this to work with SvelteKit.

The div stays black and I get the following error in console:
Bildschirm­foto 2024-03-10 um 10 13 03

Outside a Svelte component, it works fine. The strange thing is, it worked a few times within a Svelte component. But after another reload it was gone (nothing changed). Now I can't reproduce the working state ... Could you provide a SvelteKit example in StackBlitz?

Currently, I have the css and js part via CDN in app.html and also tried to load them with svelte:head inside the component.

@orestbida
Copy link
Owner

I just created a basic example here.

@orestbida orestbida removed the triage label Mar 10, 2024
@carstenjaksch
Copy link
Author

Unfortunately, that doesn't work either. I have invited you to the private repo and will send you the necessary .env contents via email.

Maybe it is a bug in this very specific context? I hope you can reproduce it.

@carstenjaksch
Copy link
Author

carstenjaksch commented Mar 12, 2024

The script seems to work after I change something and hot reload kicks in. After a full reload, the div is black again.

The services Map of im.getState() is empty after a full reload, but not with hot reload. Maybe the script runs too early?

@carstenjaksch
Copy link
Author

Finally! The simple thing is to use actions in Svelte: https://svelte.dev/docs/svelte-action

They run code after an element ist rendered to the DOM. Maybe update your Svelte example?

This is my final code:

// iframemanager.ts

import '@orestbida/iframemanager';
import '@orestbida/iframemanager/dist/iframemanager.css';

const im = (node) => {
	// @ts-ignore
	const im = iframemanager();

	im.run({
		...
	});
};

export default im;
<!-- component.svelte -->

<script lang="ts">
	import im from '$lib/Iframemanager';
</script>

<div {...dataAtts} use:im />

@driskell
Copy link

@orestbida @carstenjaksch

It worth noting that when you call run multiple times you get multiple consent notice elements added to the DOM and they start to stack up. It seems running run is not idempotent - it will in fact duplicate elements.

So I think Iframemanager as it stands does not support dynamic elements that are added after initial run is called. Perhaps needs a refresh method that just captures unknown ones and cleans up state for missing ones. run can then just reject if already been given a config.

@carstenjaksch
Copy link
Author

@orestbida I have another issue with SvelteKit. I try to load Google Maps API as a custom widget according to your demo.

Svelte:

<script>
// ...
const dataAtts = {
  'data-service': 'maps',
  'data-autoscale': '',
  'data-lat': loc[0],
  'data-lang': loc[1],
  'data-title': embed.maps.title,
  'data-phone': embed.maps.contact.phone.target,
  'data-email': embed.maps.contact.email.target
};
// ...
</script>
<!-- ... -->
<div {...dataAtts} use:im>
  <div data-placeholder>
    <div id="map"></div>
  </div>
</div>

onAccept:

onAccept: async (div, setIframe) => {
	await CookieConsent.loadScript(
		'https://maps.googleapis.com/maps/api/js?key=[API]'
	);
	await im.childExists({ childProperty: 'maps' });

	const { lat, lng, title, phone, email } = div.dataset;

	const map = new google.maps.Map(div.querySelector('#map') as HTMLElement, {
		center: { lat: Number(lat), lng: Number(lng) },
		zoom: 9
	});

	const infowindow = new google.maps.InfoWindow({
		content: `<div style="max-width: 288px; padding: 8px 20px 20px 8px;"><p style="line-height: 1.2; margin-bottom: 12px;"><strong>${title}</strong></p><p style="line-height: 1.2;">Telefon: <a href="tel:${phone}">${phone}</a><br>E-Mail: <a href="mailto:${email}">${email}</a></p></div>`,
		ariaLabel: title
	});

	const marker = new google.maps.Marker({
		position: { lat: Number(lat), lng: Number(lng) },
		map,
		title: title
	});

	infowindow.open({
		anchor: marker,
		map
	});

	marker.addListener('click', () => {
		infowindow.open({
			anchor: marker,
			map
		});
	});

	(await im.childExists({ parent: div })) && setIframe(div.querySelector('iframe'));
},

The issue: My div#maps inside the placeholder is not there (before and after accept) and the black box is spinning forever. This error follows in the browser console:

Uncaught (in promise) InvalidValueError: Map: Expected mapDiv of type HTMLElement but was passed null.

Could you provide a working example for custom widgets with SvelteKit?

Copy link

stale bot commented May 16, 2024

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label May 16, 2024
@stale stale bot closed this as completed May 25, 2024
@orestbida orestbida reopened this Sep 8, 2024
@stale stale bot removed the stale label Sep 8, 2024
@github-actions github-actions bot added the triage label Sep 8, 2024
@orestbida
Copy link
Owner

Sveltekit support should be improved in v1.3.0, thanks to the .reset() function:

<script>
    import { onMount } from 'svelte';
    import "./iframemanager";
    import "./iframemanager.css";

    onMount(() => {
        // @ts-ignore
        const im = iframemanager();

        im.run(<required_config>);

        return () => {
            im.reset();
        };
    });
</script>

@orestbida orestbida removed the triage label Sep 8, 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