Moralis is not running in Sveltekit framework?

Hi guys,

I am new developer and I want to know how to run Moralis using sveltekit. I have installed it via nodejs and tried to import it. But it’s not working and producing error process in not defined. Breaking the working of the framework too.

1 Like

Sveltekit framework may not be supported

1 Like

Hey @manishshahi, you can just easily add the two scripts in your index.html or app.html (in the head section) in your sveltekit project:

    <script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>
    <script src="https://unpkg.com/moralis/dist/moralis.js"></script>

If you want to be more secure just download the scripts and put it in your static folder if you are afraid if jsdelivr or unpkg can send malicious javascript when hacked. This works for my project (it is not the cleanest solution because it is always loaded on every page, but it is good enough for me and hopefully also for you)

4 Likes

Far from being perfect, but I made it work this way:

  1. Add web3 and moralis in to your app.html
<script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>
<script src="https://unpkg.com/moralis/dist/moralis.min.js"></script>
  1. In your __layout.svelte (or any other page you want it) add this:
<script>
   import { onMount } from 'svelte';

    async function login() {
        let user = Moralis.User.current();
        if (!user) {
            user = await Moralis.authenticate({ signingMessage: 'Log in using Moralis' })
                .then(function (user) {
                    console.log('logged in user:', user);
                    console.log(user.get('ethAddress'));
                })
                .catch(function (error) {
                    console.log(error);
                });
        } else {
            console.log(user);
        }
    }

    onMount(() => {
        const serverUrl = 'https://xxxxxxx/server';
        const appId = 'xxxxxxxxxx';
        Moralis.start({ serverUrl, appId });

        login();
    });
</script>

Note:
I was not able to make it work installing npm i moralis
But it would be awesome if the Moralis people make this package compatible with Sveltekit

2 Likes

@ishka thanks for this approach! Really helpful. I have tried to store my serverUrl and appId in .env file but it actually doesn’t working on the sveltekit.

1 Like

This is because this error:

I hope Moralis team answers soon to this one, and we can start using the sdk properly in svelte.

1 Like

Hey guys feel free to submit a PR to our public GitHub if you know how to fix this

Personally I’ve never used svelte

If you have svelte experience - check out the public GitHub and contribute with a Pr

1 Like

@ishka @manishshahi the issue and the github ticket is a bit misleading. Because Moralis SDK is using the Web3 library (where the error originates from), so you are basically talking to the wrong developers.

The error (from the screenshot) originates from the util dependency, which is used by the web3-core-requestmanager and web3-core dependency and the web3 package and finally the Moralis npm package (check the browser while reproducing the error and view the callstack in your developer tools). Sveltekit is still in beta and still resolving issues as we speak (Rich Harris is now working full time on it, so we can hope it will be fixed in the next vite/sveltekit release cycle or eventually has a good solution before releasing 1.0), so demanding Moralis to find answers soon is a bit too much in my opinion and the work around I posted is good enough for beta software I think.

Also you have a lot of different adapters @ishka which means that your code in __layout.svelte will not work for certain adapters and settings (if you want to make it safe wrap it in a if statement where you check if you are in browser from the $app/env store).

When Sveltekit 1.0 is released I will check again if Moralis still doesn’t work nicely enough with sveltekit and will probably do a PR if I feel it is not out of scope of their codebase and their dependencies.

1 Like

Thanks for sharing this information. It was very useful.

1 Like

Sveltekit + Moralis (web3) + Lens Protocol Setup, I spent a few days configuring it.

The application is simple, there will be only one button written “click” on the page, when you click it you will be redirected to the profile/[lens profile wallet address] page.
When you enter the page the server will read the params.slug and pass it to the getWalletNFTs method of Moralis, then the server will return all the NFTs of the user’s wallet and finally the NFTs will be shown in the console.

Example:
http://localhost:5173/profile/0xD28E808647D596F33Dcc3436E193A9566fc7aC07

Dependencies
npm i -D @urql/svelte
npm moralis

Final code:

_.env
_📁 src
__ :file_folder: lib
___ :atom_symbol: lensCall.ts
__ :file_folder: routes
___ :file_folder: (unauthed)
____ :file_folder: profile
_____ :file_folder: [slug]
______ :atom_symbol: +page.server.ts
______ :atom_symbol: +page.svelte
_____ :atom_symbol: +page
____ :atom_symbol: +layout.server.ts
____ :atom_symbol: +layout.svelte
____ :atom_symbol: +page.svelte

.env
MORALIS_API_KEY=""

src/lib/lensCall.ts

import { createClient } from '@urql/svelte'

export const client = createClient({
	url: 'https://api.lens.dev'
})

src/routes/(unauthed)/profile/[slug]/+page.server.ts

import Moralis from 'moralis'
import { error } from '@sveltejs/kit'
import type { PageServerLoad } from './$types'

export const load = (async ({ params }) => {
	if (params.slug) {
		try {
			const nfts = await Moralis.EvmApi.nft.getWalletNFTs({
				address: params.slug,
				chain: 0x89
			})

			const result = nfts.toJSON()

			return { result }
		} catch (err) {
			throw error(404, 'Not found')
		}
	}
}) satisfies PageServerLoad

src/routes/(unauthed)/profile/[slug]/+page.svelte

<script lang="ts">
	import type { PageData } from './$types'

	export let data: PageData

	console.log(data)
</script>

<svelte:head>
	<title>Profile page</title>
	<meta name="description" content="Svelte demo app" />
</svelte:head>

<section />

<style>
</style>

src/routes/(unauthed)/profile/+page

<script lang="ts">
	import type { PageData } from './$types'

	export let data: PageData
</script>

<svelte:head>
	<title>Profile</title>
	<meta name="description" content="Svelte demo app" />
</svelte:head>

<style>
</style>

src/routes/(unauthed)/+layout.server.ts

import Moralis from 'moralis'
import { env as private_env } from '$env/dynamic/private'

Moralis.start({
	apiKey: private_env.MORALIS_API_KEY
})

src/routes/(unauthed)/+layout.svelte

<script lang="ts">
	import { client } from '$lib/lensCall'
	import { setContextClient } from '@urql/svelte'

	setContextClient(client)
</script>

<slot />

<style global windi:global windi:preflights:global windi:safelist:global>
</style>

src/routes/(unauthed)/+page.svelte

<script lang="ts">
	import { getContextClient, gql, queryStore } from '@urql/svelte'
	import { goto } from '$app/navigation'

	const handleClick = () => {
		goto(`profile/${ownedBy}`)
	}

	let ownedBy = ''

	try {
		const profileQuery = gql`
			query Profile {
				profile(request: { profileId: "0x01" }) {
					id
					name
					bio
					attributes {
						displayType
						traitType
						key
						value
					}
					followNftAddress
					metadata
					isDefault
					picture {
						... on NftImage {
							contractAddress
							tokenId
							uri
							verified
						}
						... on MediaSet {
							original {
								url
								mimeType
							}
						}
						__typename
					}
					handle
					coverPicture {
						... on NftImage {
							contractAddress
							tokenId
							uri
							verified
						}
						... on MediaSet {
							original {
								url
								mimeType
							}
						}
						__typename
					}
					ownedBy
					dispatcher {
						address
						canUseRelay
					}
					stats {
						totalFollowers
						totalFollowing
						totalPosts
						totalComments
						totalMirrors
						totalPublications
						totalCollects
					}
					followModule {
						... on FeeFollowModuleSettings {
							type
							amount {
								asset {
									symbol
									name
									decimals
									address
								}
								value
							}
							recipient
						}
						... on ProfileFollowModuleSettings {
							type
						}
						... on RevertFollowModuleSettings {
							type
						}
					}
				}
			}
		`

		const returnedProfile = queryStore({
			client: getContextClient(),
			query: profileQuery
		})

		returnedProfile.subscribe((result) => {
			ownedBy = result?.data?.profile.ownedBy
		})
	} catch (error) {
		console.log(error)
	}
</script>

<svelte:head>
	<title>Main page</title>
	<meta name="description" content="Svelte demo app" />
</svelte:head>

<button on:click|preventDefault={handleClick}>click</button>

<style>
</style>

The issue: https://github.com/0xFernandoDias/metrohouse.app/issues/18#issuecomment-1372606087

2 Likes