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

Setup Preact via <script> tag? #484

Closed
rafaelferreiraql opened this issue Jan 2, 2017 · 11 comments
Closed

Setup Preact via <script> tag? #484

rafaelferreiraql opened this issue Jan 2, 2017 · 11 comments

Comments

@rafaelferreiraql
Copy link

With React, you could simply upload it on your page via <script> tags, but the Preact docs only ever mention the npm route. At the same time, I'm aware Preact is hosted on cdnjs, but it doesn't seem to work, it's tailored to work only with ES6 import (which has no support from any browser).

@developit
Copy link
Member

developit commented Jan 2, 2017

@rafaelferreiraql It works fine from the CDN. Preact and the examples are written in ES2015, but everything is actually shipped as ES3 / ES5.

A while back we created an example project for this type of a setup (no webpack, transpilers, any of that - just script tags in an HTML page). You might find it useful: https://github.com/developit/preact-in-es3

To answer your question though, here's a working cdnjs example (view on JSFiddle):

<script src="https://cdnjs.cloudflare.com/ajax/libs/preact/7.1.0/preact.js"></script>
<script>
  var h = preact.h;  // for convenience

  // an App classful component
  function App() {}
  App.prototype.render = function(props, state) {
    return h('div', { class:'app' },
      h('h1', null, 'Hello, World!'),
      h('ol', null,
        h('li', null, 'Item One'),
        h('li', null, 'Item Two')
      )
    );
  };

  // render <App /> into <body>
  preact.render(
    h(App),
    document.body
  );
</script>

If you want to use Babel in your page, while I strongly recommend against doing so, it works identically to React. You will need to tell Babel to transform your JSX to h() calls instead of React.createElement(), or alias it:

<!-- option 1: alias it -->
<script>window.React = { createElement: preact.h }</script>
<script type="text/babel">
  preact.render(<h1>Demo</h1>, document.body);
</script>

<!-- option 2: tell Babel to use h() -->
<script type="text/babel">
  /** @jsx h */
  preact.render(<h1>Demo</h1>, document.body);
</script>

@noway
Copy link

noway commented Jan 4, 2017

You can also use unpkg.com:

    <script src="https://unpkg.com/preact@7.1.0"></script>

@developit
Copy link
Member

developit commented Jan 4, 2017

yup yup. #protip the minified version is on there too:
<script src="//unpkg.com/preact/dist/preact.min.js"></script>

@rafaelferreiraql
Copy link
Author

It's a relief it's supposed to work via CDN too!

In fact, I found out what was the problem, I just didn't try to prefix h() or render(). In hindsight, those would be pretty nasty global variables to begin with.

Thanks for your help!

@avinashdvv
Copy link

@developit how App is added to h function in preactjs if we write JSX?

@lukeed
Copy link
Member

lukeed commented Jul 19, 2018

@avinashdvv To use JSX in a script tag, you'll need to include Babel runtime on your page as well. As mentioned above, it's recommended to avoid this if possible. However, if this is still something you need to do, you must include a JSX transformer preset or plugin for Babel (eg, babel-preset-react) and then tell Babel to use h or preact.h.

/* @jsx preact.h */
preact.render(<h1>Demo</h1>, document.body); 

// or:

/* @jsx h */
var { render, h } = preact;
render(<h1>Demo</h1>, document.body); 

You're much better off (IMO) using the h() function directly since that's what Babel is returning as output anyway. I'd recommend you revisit Jason's answer above (#484 (comment)) for more info.

@arnavzek
Copy link

It's very simple

<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.24.0/babel.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/preact/7.1.0/preact.js"></script>
<script>window.React = { createElement: preact.h }</script>

<script type='text/babel'>
    preact.render(<h1>we love preact</h1>, document.body);
 </script>

</head>
<body>
</body>
</html>

@ForsakenHarmony
Copy link
Member

well if you use what luke posted above, you don't need to define window.React

@hacker-DOM
Copy link

#484 (comment)

This snippet no longer works (it works as is, but not when preact==10.11.3 is loaded. It seems the new version no longer sets global.preact)

@developit
Copy link
Member

@hacker-DOM the file is now called preact.min.js on that CDN (not sure why):

<script src="https://cdnjs.cloudflare.com/ajax/libs/preact/10.11.3/preact.min.js"></script>

@developit
Copy link
Member

For anyone finding this issue via Google, please use HTM instead of h() or Babel. It has vastly better performance than running Babel in your page, and is easier to type than h().

Preferred Script Tag Solution (2023)

<script type="module">
  import { Component, render } from 'https://esm.sh/htm/preact';
  import { html } from 'https://esm.sh/htm/preact';

  /** If you're using hooks, you can import that from unpkg too: */
  // import { useState } from 'https://esm.sh/preact/hooks';

  function App() {
    return html`
      <div class="app">
        <h1>Hello, World!</h1>
        <ol>
          <li>Item One</li>
          <li>Item Two</li>
        </ol>
      </div>
    `;
  }

  // render <App /> into <body>
  render(html`<${App} />`, document.body);
</script>
Or, if you can't use ES Modules
<!-- Load Preact's UMD build from CDNJS: -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/preact/10.11.3/preact.min.js"></script>

<!-- Load HTM from CDNJS: -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/htm/3.1.1/htm.min.js"></script>

<!-- If you're using hooks, you can get that from CDNJS too: -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/preact/10.11.3/hooks.umd.js"></script>

<script>
  const { h, Component, render } = preact;
  const html = htm.bind(h);

  function App() {
    return html`
      <div class="app">
        <h1>Hello, World!</h1>
        <ol>
          <li>Item One</li>
          <li>Item Two</li>
        </ol>
      </div>
    `;
  }

  // render <App /> into <body>
  render(html`<${App} />`, document.body);
</script>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants