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

External scripts don't work #306

Open
iliakan opened this issue Sep 3, 2024 · 6 comments
Open

External scripts don't work #306

iliakan opened this issue Sep 3, 2024 · 6 comments

Comments

@iliakan
Copy link

iliakan commented Sep 3, 2024

Describe the bug

Adding an external script to a lesson doesn't work.

Steps to reproduce

  1. Add <script src="landing.js"></script> to content.md of a lesson.
  2. Create landing.js file with console.log(1) in the lesson folder.
  3. Run npm run dev and open the lesson in the browser.
  4. The script is not executed - the corresponding HTTP request returns 404.

Expected behavior

Astro supports scripts. I'd expect the script to work.

Platform

  • TutorialKit version: github latest.
  • OS: macOS
  • Browser: Chrome

P.S.

Adding image.png to the lesson and including it as ![](ball.png) works.

Perhaps, there's an alternative "proper" way to add an external script?

@AriPerkkio
Copy link
Member

AriPerkkio commented Sep 3, 2024

I'm not sure if Astro supports this out-of-the-box (cc. @Nemikolh, ???). But one thing you could do is convert the content.md into content.mdx, import the script contents as raw string and add it to markup:

---
type: lesson
title: Example
---

import landing from "./_files/landing.js?raw"

# Test

<script>
  {landing}
</script>

But if you just want to add some interactivity to lesson markdown, I would recommend to check Astro docs: https://docs.astro.build/en/basics/astro-components/ and https://docs.astro.build/en/guides/client-side-scripts/

@Nemikolh
Copy link
Member

Nemikolh commented Sep 3, 2024

With Astro's content collection, I would advise against having code that is part of your app inside your content/* folders (the only exception being content/config.ts which is treated specially by Astro).

I find that it's usually nicer to have the following structure:

src
├── utils
│   └── script.ts
├── content
│   ├── config.ts
│   └── tutorial
│       ├── meta.md
│       └── ...
...

Which then let you import your script like this in any content.mdx:

---
type: lesson
title: Example
---

import "@utils/script";

# My lesson

The nice thing is that you can import your script using the same import in any lesson.

If you want to add a ui element, you might find it useful to have a component instead which let's you access and modify the state of the tutorial:

With a src/components/UpdateFileButton.tsx file:

import tutorialStore from 'tutorialkit:store';

interface Props {
  path: string;
  content: string;
}

export function UpdateFileButton({ path, content }: Props) {
  function writeFile() {
    tutorialStore.updateFile(path, content);
  }

  return (
    <button onClick={writeFile}>
      Update file
    </button>
  );
}

You can then use it like this in your lessons:

---
type: lesson
title: Example
---

import { UpdateFileButton } from "@components/UpdateFileButton";

# My lesson

<UpdateFileButton client:load path="/index.js" content="console.log('Hello world!')" />

@iliakan
Copy link
Author

iliakan commented Sep 4, 2024

So it's ok to put images in content, but not scripts? Even if the script is for a particular lesson only?

@AriPerkkio
Copy link
Member

@iliakan could you describe your use case a bit more? What does the landing.js do? Why does it need to be run outside webcontainer as well?

@iliakan
Copy link
Author

iliakan commented Sep 4, 2024

@AriPerkkio for this particular case I was going to create a landing script to nicely show callouts above the webcontainer and the editor, to introduce the environment in a clear visual style.

@Nemikolh
Copy link
Member

Nemikolh commented Sep 5, 2024

So it's ok to put images in content, but not scripts? Even if the script is for a particular lesson only?

I mean you can also have them there but it won't be as nice as having them outside in terms of DX with vite because we exclude those folders from vite's optimizeDeps entry:

vite: {
optimizeDeps: {
entries: ['!**/src/(content|templates)/**'],

So IIRC, it means that vite won't be scanning those scripts and they might load a bit slower in development.

Note that they are excluded for a reason: we do not want vite to try to resolve imports for file that ends in WebContainer as it leads to confusing errors

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