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

Question about accessing chrome APIs correctly #32

Open
sullyj3 opened this issue Dec 19, 2023 · 3 comments
Open

Question about accessing chrome APIs correctly #32

sullyj3 opened this issue Dec 19, 2023 · 3 comments

Comments

@sullyj3
Copy link

sullyj3 commented Dec 19, 2023

Hi! I'm trying to write an extension which accesses the chrome bookmarks API, but I'm having some trouble understanding how to use it correctly in the context of sveltekit. I started from this template repository.

To start with I wanted to just display a BookmarkTreeNode, so I edited src/routes/+page.svelte with the following:

(here's the docs for chrome.bookmarks.getTree)

<script lang='ts'>
    import { onMount } from 'svelte';

    let bookmarksPromise: Promise<chrome.bookmarks.BookmarkTreeNode[]>;

    onMount(() => {
        if (window.chrome && chrome.runtime && chrome.runtime.id) {
            bookmarksPromise = chrome.bookmarks.getTree();
        }
    });
</script>

<div class="container h-full mx-auto flex justify-center items-center">
    <div class="space-y-10 text-center flex flex-col items-center">
        <h2 class="h2 font-bold">Welcome to Skeleton.</h2>
        <div class="space-y-2">
            <p>hello, world!</p>
            {#await bookmarksPromise}
                <p>loading bookmarks...</p>
            {:then bookmarks}
                <p>bookmarks loaded!</p>
                <pre>{JSON.stringify(bookmarks, null, 2)}</pre>
            {:catch error}
                <p>error loading bookmarks: {error.message}</p>
            {/await}
        </div>
    </div>
</div>

This works as expected, displaying this JSON:

[
  {
    "children": [
      {
        "children": [],
        "dateAdded": 1702963434117,
        "id": "1",
        "index": 0,
        "parentId": "0",
        "title": "Bookmarks bar"
      },
      {
        "children": [],
        "dateAdded": 1702963434117,
        "id": "2",
        "index": 1,
        "parentId": "0",
        "title": "Other bookmarks"
      }
    ],
    "dateAdded": 1702963434117,
    "id": "0",
    "title": ""
  }
]

The problem comes in when I try to actually access the node. When I edit the html with the following instead:

            {#await bookmarksPromise}
                <p>loading bookmarks...</p>
            {:then bookmarks}
                <p>bookmarks loaded!</p>
                <!-- for some reason getTree returns an array containing the single root `BookmarkTreeNode` -->
                <!-- so we need to index it to access the node -->
                <pre>{JSON.stringify(bookmarks[0], null, 2)}</pre>
            {:catch error}
                <p>error loading bookmarks: {error.message}</p>
            {/await}

I get a compile error:


TypeError: Cannot read properties of undefined (reading '0')
    at file:///home/james/dev/popmark-svelte/.svelte-kit/output/server/entries/pages/_page.svelte.js:16:112
    at file:///home/james/dev/popmark-svelte/.svelte-kit/output/server/entries/pages/_page.svelte.js:17:6
    at file:///home/james/dev/popmark-svelte/.svelte-kit/output/server/entries/pages/_page.svelte.js:18:4
    at Object.$$render (file:///home/james/dev/popmark-svelte/.svelte-kit/output/server/chunks/ssr.js:104:18)
    at Object.default (file:///home/james/dev/popmark-svelte/.svelte-kit/output/server/chunks/internal.js:68:98)
    at Object.default (file:///home/james/dev/popmark-svelte/.svelte-kit/output/server/entries/pages/_layout.svelte.js:167:47)
    at file:///home/james/dev/popmark-svelte/.svelte-kit/output/server/entries/pages/_layout.svelte.js:147:909
    at Object.$$render (file:///home/james/dev/popmark-svelte/.svelte-kit/output/server/chunks/ssr.js:104:18)
    at file:///home/james/dev/popmark-svelte/.svelte-kit/output/server/entries/pages/_layout.svelte.js:152:55
    at Object.$$render (file:///home/james/dev/popmark-svelte/.svelte-kit/output/server/chunks/ssr.js:104:18)

node:internal/event_target:1083
  process.nextTick(() => { throw err; });
                           ^
Error: 500 /
To suppress or handle this error, implement `handleHttpError` in https://kit.svelte.dev/docs/configuration#prerender
    at file:///home/james/dev/popmark-svelte/node_modules/@sveltejs/kit/src/core/config/options.js:212:13
    at file:///home/james/dev/popmark-svelte/node_modules/@sveltejs/kit/src/core/postbuild/prerender.js:64:25
    at save (file:///home/james/dev/popmark-svelte/node_modules/@sveltejs/kit/src/core/postbuild/prerender.js:403:4)
    at visit (file:///home/james/dev/popmark-svelte/node_modules/@sveltejs/kit/src/core/postbuild/prerender.js:236:3)
Emitted 'error' event on Worker instance at:
    at [kOnErrorMessage] (node:internal/worker:326:10)
    at [kOnMessage] (node:internal/worker:337:37)
    at MessagePort.<anonymous> (node:internal/worker:232:57)
    at [nodejs.internal.kHybridDispatch] (node:internal/event_target:807:20)
    at exports.emitMessage (node:internal/per_context/messageport:23:28)

Node.js v20.6.1
 ELIFECYCLE  Command failed with exit code 1.

referring to the bookmarks[0] in the html. I'm a bit hazy on how sveltekit works, but my intuition says the error is to do with SSR and the bookmarks not being available when the page is being prerendered? Is that right?

How do I do this correctly?

@michmich112
Copy link
Owner

The best solution for this would be to add typing for the chrome api with this package. I'm looking into ways to add it for intellisense to also pick up and use it correctly

@ahanprojects
Copy link

ahanprojects commented Jun 6, 2024

I am also using chrome API (chrome.storage.local). Because this API can only be accessed from the client, I set prerender = true and ssr = false in +layout.ts. While developing, I use localStorage to mock the behavior of chrome.storage.local, and it works fine.

But when I build the app and unpack it, then open the extension, it shows 404 not found. The console error says Error: Not found: /index.html, even though the index.html file is present on the build folder. I suspect the problem comes from the script tag inside index.html.

If i remove ssr = false, the extension works fine, but I have to make a lot of adjustment (like using onMount and browser variable) to make sure chrome.storage.local only called in the browser, which is a lot of hassle and not very clean, because I have to do this in multiple files.

My question is, does this adapter doesn't work for ssr = false? or maybe there is something wrong my implementation? Thankyou in advance!

@michmich112
Copy link
Owner

HEy @ahanprojects
yes this adapter won't work for ssr = false the reason being that it needs to have fully resolved and injectable html and js to package it as an extension.
Without ssr = false the svelte compiler will create a server package that will need to run on another environment than the browser, and the resulting html and js will require a connection to that server to load and render.

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