GithubHelp home page GithubHelp logo

capri-js / capri Goto Github PK

View Code? Open in Web Editor NEW
204.0 3.0 5.0 2.54 MB

Build static sites with interactive islands

Home Page: https://capri.build

License: MIT License

TypeScript 84.71% JavaScript 14.16% HTML 1.13%
static-site-generator

capri's Introduction

Capri

Capri allows you to build static websites using a frontend framework of your choice (React/Preact/Vue/Solid/Svelte).

Carbon-friendly 🌱

By default, zero KB of JavaScript is shipped to the browser.

You can sprinkle in client-side interactivity by turning some of your components into islands. Capri will make sure, that only that part of your JavaScript is sent down the wire that is required to let these islands become interactive.

Use what you already know 🎓

With Capri, you don't have to learn any new APIs. In fact, Capri doesn't even have an API! Use your framework's regular ecosystem as if you were building a single page app and follow these two rules:

  1. 📍 Pick a router that supports server-side rendering (pretty much all popular routing libraries do this).
  2. 🏝️ If a component needs to become interactive, name it *.island.*. Capri will take care of the rest.

👉 Visit https://capri.build to get started.

No lock-in 🔓

Should you ever decide to remove Capri from your project, you will be left with a 100% working Vite app. Of course, instead of pre-rendered static pages, the output will then be a regular SPA.

Bonus: Live CMS previews 🔮

When you connect your Capri website to a headless CMS, you can take further advantage of Capri's architecture, as it allows you to generate a separate SPA version of your site that can be used to live-preview any content changes without requiring a build-step or server-side rendering. You can use cheap and energy efficient static file hosting and still get real-time previews right inside your CMS.

License

MIT

capri's People

Contributors

semantic-release-bot avatar fgnass avatar dependabot[bot] avatar

Stargazers

Divansh avatar Khant Zin Thu avatar Faiza Bilal avatar Jelle Biesemans avatar  avatar Zoxon avatar Tristan Yang avatar Roman Lefter avatar  avatar Seigo Mori avatar Karim Ould Mahieddine avatar Christophe avatar Alexey Elizarov avatar Sebastián García avatar Rustie avatar Sebastian Himberger avatar Alexandr Trachuk avatar Hrihorii Ilin avatar Benjamin Singer avatar Leon avatar  avatar Thibaud Colas avatar  avatar Mathieu Laurent avatar Efrén Carbajal avatar Cedd Burge avatar Tuan Duc Tran avatar Mariano Portal avatar Nailton avatar Harsh Pratap Singh avatar Declan avatar Neil Parikh avatar Tim Moser avatar Matt Zimmermann avatar Alexis Delrieu avatar Newman avatar MO avatar Santhosh Veer avatar Jiajun Chen avatar Mark Otto avatar stieglitzz avatar Shayon avatar Rizkyy avatar Alex Kreidler avatar Ricky avatar 波比小金刚 avatar Lar Van Der Jagt avatar Kyriakos-Ioannis D. Kyriakou avatar Kengo Yamashita avatar Chaoky avatar Sergey Shishkin avatar Michael van Engelshoven avatar Luke Secomb avatar ⊣˚∆˚⊢ avatar Arstneio avatar Patrick Arminio avatar John S. Dvorak avatar Felix Hungenberg avatar Nir Zilberman avatar Peter W avatar Vladimir Chirikov avatar YM avatar Ted Lindholm avatar Olivér Mrakovics avatar Alex Strand avatar Bryan Hyshka avatar Álvaro García León avatar  avatar Hamza Tekin avatar Burner avatar Jonathan Triff avatar YangJH avatar  avatar Bartłomiej Olejnik avatar ahrbil avatar Bahlul Hasanli avatar Ali Heydari avatar Alejandro avatar RanolP avatar Worakarn  (Peter) Ounhattapradit avatar Sujan Tamang avatar Teerapat Prommarak avatar Yusuke Wada avatar Eka Prasetia avatar Lawrence Onah avatar jinho park avatar Karol Fabjańczuk avatar Robert Soriano avatar Will Caulfield avatar Quinn Blenkinsop avatar Winston Fassett avatar Fatih Aygün avatar Dario Ielardi avatar Mateusz Kadlubowski avatar Derrick Farris avatar Ilia Shabanov avatar  avatar Néstor avatar Andrés Reyes avatar Luís Rodrigues avatar

Watchers

 avatar  avatar RyShuey avatar

capri's Issues

Typo in data fetching example

There's a small typo in the data fetching example which is hard to detect and which prevents data loading for static builds:

https://capri.build/docs/frameworks/react/

const user = useSWR("https://api.example.com", fetcher, { suspsense: true });

Should be:

const user = useSWR("https://api.example.com", fetcher, { suspense: true });

It needs to be suspense instead of suspsense.

Capri as "view engine"?

Hello!

I am working on writing an application with NestJS as the underlying framework. Being used to MVC-style web app development from years and years of PHP, I just can't get this out of my system... ^^;

Now, I would like to use sporadic JS here and there - like when a user clicks a profile image, it shows a lightbox with a higher resolution image. Something you see a lot like on eBay and Amazon. But I would love to use the islands approach as to only load the JS when it is actually needed.

This has led me to checking out a few frameworks that had "islands" somewhere within their project's description, and thus I found Capri. :)

Is it possible to use Capri to substitude the view engine and introduce the islands pattern to it? I am using Mustache templates because they are fast and very simple - at the moment, at least. When a controller encounters an API request (HTTP GET (...) Accept: text/json), it'll only return the JSON data - but in any other case, it would normally return a view. The default behaviour in most MVCs is to just render a template and return the full page.

My thought-process is, that instead of rendering a template, I would render a component with Capri in SSR and return the stringified output, hydrating at the client side when required (i.e.: the user clicks the image). I am convinced that this should be possible...but I wanted to hear your thoughts on this approach :)

Thanks for this fun framework and have a great day!

Kind regards,
Ingwie

Capri with firebase

Hello, i like using capri
i've research interesting todo with capri which i have a cms and integrate it with capri

but also i've use firebase for register any user data.

When build it the submit data fn which call a firebase not work when debuggin in network.
So does capri separate a ssr and csr pages?

in local development its work but when build it didnt post any data

SSR

Hello and thanks for this awesome project!

As mentioned in motivation section, Capri fits quite unique set of goals, while alternatives are hard to find. SSR is mentioned as experimental with the focus on SSG. But one popular use-case — ecommerce —actually can benefit hugely from Capri, but it often requires SSR due to a more dynamic nature. Also SSR capability makes Capri even more unique.

Could SSR be made a first-class citizen for Capri?

[react] Suspense for Data Fetching + Static Site Generation?

We would like to use Suspense for Data Fetching in an SSG setup (Capri + React).

The idea is to use renderToPipeableStream() + onAllReady() or
renderToReadableStream() + await stream.allReady to get the final markup after all suspense boundaries have resolved.

This already works when using SWR 1.x, but SWR 2.x will no longer run on the server as it has no way of transferring the data to the client.

I understand that the way forward for SSR will be React Server Components, but this doesn't sound like a viable solution for generating static markup.

I could imagine that using a primitive like react-fetch would be a suitable option in the future, but currently react-dom/serverdoes not implement getCacheForType() so this does not work (yet?).

I guess the question boils down to this: Will there be a supported way to use Suspense for Data Fetching in an SSG context, or will we need to fetch the data outside of React with a Next.js-style getStaticProps pattern?

React helmet

Hi,

I like capri and it useful library...

I'm actually working on head seo tag and i've try to add react helmet but not successfully.
Do you have any example or suggestion how to implement it ?

regards

Vincent

Missing @types/node

After running yarn create capri my-app -e react, vite.config.ts will use process yet @types/node is not installed, making TypeScript unhappy. It should be added as dev dependency to the package.json to fix this issue.

I couldn't figure how to send a PR for that though because I didn't find where the template projects are defined?

🐛 BUG: Creating a new Capri with SolidJS

  • using @capri-js/solid (v4.0.1).
  • using Node that supports ESM (v16.15.1).
  • using NPM
  • using Linux

Bug:

First issue seems to expect vite.config.js as vite.config.ts.js is generated.

failed to load config from /home/user/code/broken/vite.config.ts
error when starting dev server:
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/home/user/code/broken/node_modules/@capri-js/solid/lib/index.js' imported from /home/user/code/broken/vite.config.ts.js

Then the node_modules path seems incorrect as it's targeting lib but contains /home/user/code/broken/node_modules/@capri-js/solid/src?

failed to load config from /home/user/code/broken/vite.config.js
error when starting dev server:
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/home/user/code/broken/node_modules/@capri-js/solid/lib/index.js' imported from /home/user/code/broken/vite.config.js

I assume there has been a missing compile step as /home/user/code/broken/node_modules/@capri-js/solid/src contains typescript and or incorrect paths? as I can see /home/user/code/broken/node_modules/capri contains a lib folder containing both typescript and JavaScript.

Hot Reload resulting in blank pages.

One problem that I've had with Capri was the Hot Reload, seems that every Hot Reload makes Vite return the virtual/client.js file without the entry code, I can reproduce it just by running the preact example and changing the main.tsx file, here is the content Vite serves before the changes:

// http://127.0.0.1:5173/src/main.tsx
import.meta.env = {
    "BASE_URL": "/",
    "MODE": "development",
    "DEV": true,
    "PROD": false,
    "SSR": false
};
import "/node_modules/.vite/deps/preact_debug.js?v=a38e079f";
var _jsxFileName = "/Users/peixe/Projects/my-capri-site/src/main.tsx";
import {render} from "/node_modules/.vite/deps/preact.js?v=a38e079f";
import {Router} from "/node_modules/.vite/deps/wouter-preact.js?v=a38e079f";
import {App} from "/src/App.tsx";
import {PreviewBanner} from "/src/Preview.tsx";
import {jsxDEV as _jsxDEV} from "/node_modules/.vite/deps/preact_jsx-dev-runtime.js?v=a38e079f";
const base = import.meta.env.BASE_URL.slice(0, -1);
render(_jsxDEV(Router, {
    base,
    children: [_jsxDEV(PreviewBanner, {}, void 0, false, {
        fileName: _jsxFileName,
        lineNumber: 12,
        columnNumber: 5
    }, void 0), _jsxDEV(App, {}, void 0, false, {
        fileName: _jsxFileName,
        lineNumber: 13,
        columnNumber: 5
    }, void 0)]
}, void 0, true, {
    fileName: _jsxFileName,
    lineNumber: 11,
    columnNumber: 3
}, void 0), document.body);

Here is the content after the changes:

// http://127.0.0.1:5173/src/main.tsx?t=1677586235225
import "/node_modules/.vite/deps/preact_debug.js?v=a38e079f";
import "/@id/__x00__virtual:capri-hydration";

Seems that the t query parameter is added but it seems to have no effect on what Vite serves as the main.tsx file. To fix this issue I've changed the line 26 at https://github.com/capri-js/capri/blob/main/packages/capri/src/wrapper.ts from

if (isWrapperInfo(info)) {

to

if (process.env.NODE_ENV === "production" && isWrapperInfo(info)) {

Seems that this.getModuleInfo(id) returns {} when the project starts, adding the wrapper and wrapped values when hot reload is called. Seems the meta properties are only being added after the Hot Reload and I couldn't find the reason why.

I would like to know if you have any ideas on what could be happening here, if not I guess I will continue my debugging session.

weird issue with dep optimisation

I came across this while migrating a project from Astro,
I imagine that it comes from Vite trying to optimise deps, but I'm not sure

https://github.com/Typeform/embed/tree/main/packages/embed-react

only works in dev mode

import { SliderButton } from "@typeform/embed-react";

only works at build time

import typeform from "@typeform/embed-react";
const { SliderButton } = typeform

works at build time and dev mode

import * as typeFrom from "@typeform/embed-react";
const { SliderButton } = typeFrom.default ?? typeFrom

error sample:

[vite-plugin-capri-main] Named export 'SliderButton' not found. The requested module '@typeform/embed-react' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from '@typeform/embed-react';
const { SliderButton } = pkg;

error during build:
file:///home/lordie/Projects/nano/mono/my-capri-site/dist/ssr.js:10
import { SliderButton } from "@typeform/embed-react";
         ^^^^^^^^^^^^
SyntaxError: Named export 'SliderButton' not found. The requested module '@typeform/embed-react' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from '@typeform/embed-react';
const { SliderButton } = pkg;

    at ModuleJob._instantiate (node:internal/modules/esm/module_job:124:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:190:5)
 ELIFECYCLE  Command failed with exit code 1.

Preact example is missing dependency "preact-render-to-string"

When I create a preact project with npm init capri my-capri-site -- -e preact, the build fails because preact-render-to-string is not installed.

Edit: I just tested by cloning the capri repo and then the example works (after npm install in root).

I am using yarn instead of npm. Maybe that is the problem. I see that @capri-js/preact depends on preact-iso, which in turn depends on preact-render-to-string.

Node: 16.13.2
Yarn: 1.22.15

Usage alongside a Meta-Framework

Hi. I would like to use Capri along with vite-plugin-ssr. Capri prompts an error saying "Can't find index.html" due to VPS not having an index file.
The same problem happens with SvelteKit, making Capri only useful when used as a meta-framework which is a position where it lacks functionality like APIs or Routing.
Capri is currently the only one that has the islands the way I like it and is maintained, that's why I would like to have this being discussed, this is the error I've mentioned before:

Error: Can't find index.html in /Users/peixe/Projects/preact-client-routing
    at getIndexHtml (file:///Users/peixe/Projects/preact-client-routing/node_modules/.pnpm/[email protected][email protected]/node_modules/capri/lib/entry.js:13:15)
    at getEntryScript (file:///Users/peixe/Projects/preact-client-routing/node_modules/.pnpm/[email protected][email protected]/node_modules/capri/lib/entry.js:24:23)
    at getEntryScripts (file:///Users/peixe/Projects/preact-client-routing/node_modules/.pnpm/[email protected][email protected]/node_modules/capri/lib/entry.js:41:17)
    at config (file:///Users/peixe/Projects/preact-client-routing/node_modules/.pnpm/[email protected][email protected]/node_modules/capri/lib/vite-plugin.js:43:25)
    at runConfigHook (file:///Users/peixe/Projects/preact-client-routing/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/chunks/dep-ca21228b.js:62375:31)
    at async resolveConfig (file:///Users/peixe/Projects/preact-client-routing/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/chunks/dep-ca21228b.js:61876:14)
    at async createServer (file:///Users/peixe/Projects/preact-client-routing/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/chunks/dep-ca21228b.js:61153:20)
    at async CAC.<anonymous> (file:///Users/peixe/Projects/preact-client-routing/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/cli.js:734:24)

hmr fails with unamed components

using

export default function() {
  useStatus(404);
  return (
    <main>
      <h1>404 - Not found.</h1>
    </main>
  );
}

instead of

export default function NotFound() {
  useStatus(404);
  return (
    <main>
      <h1>404 - Not found.</h1>
    </main>
  );
}

makes capri display a blank screen when changes are made to source code

Various improvements to the React boilerplate

Hi,

I am working on a project currently and I wanted to documented a few possible improvements for the React boilerplate (I might PR them when I am done):

  • There is no 404 setup. We need to add <Route path="*" element={NotFound} /> in App. I couldn't find any official doc about this though, some people seem to debate whether this Route should be the first or the last, or if "path" is necessary... Route component doc doesn't help much. Using it as the first route like this seems to work as expected in my app.
  • Path aliases are really useful, they could be configured as a default (need to be done in both vite.config.ts and tsconfig.json)
// tsconfig.json
    "paths": {
      "~/*": "src/*"
    }
// vite.config.ts
  resolve: {
    alias: {
// TS will cringe => see next point about tsconfig
      "~": path.resolve(__dirname, "./src"),
    },
  },
  • tsconfig.json should probably be put into src and not at the root. Otherwise, you cannot add a tsconfig at the root of the project for configs (eg having node types loaded to correctly type vite.config.ts. Then you can add a tsconfig.js at the root that is targeted at root config files only. I haven't tested that because we probably need to explicitely tell Vite to look for src/tsconfig.json instead of tsconfig.json. This is the pattern preferred in Next.js apps as well.
  • I couldn't have Tailwind to work properly, almost everything work, except that "className='py-2' in a .tsx file won't do anything. It seems that the "py-2" class isn't loaded properly, because if I had "py-2" in index.html, it does apply the style, but also starts working again in the ".tsx" component. Basically, during the step where Tailwind plugins collects all the classes used in your app, it only takes "index.html" into account. I've followed the basic Vite install process, nothing fancy.

SSR build for vue not output server side

Expect:

  • Able to run yarn build and deploy using build output

Actual:

  • Serve dist will return a blank page

Logs

  • Start project using command npm init capri demo-capri -- -e vue
  • Run yarn build
yarn build
yarn run v1.22.19
$ vite build && vite build --ssr
vite v2.9.13 building for production...
✓ 40 modules transformed.
dist/assets/capri.ce1c56b3.svg                     1.38 KiB
dist/preview/index.html                            1.02 KiB
dist/index.html                                    0.65 KiB
dist/ssr-manifest.json                             2.74 KiB
dist/assets/index.12a53772.js                      0.23 KiB / gzip: 0.16 KiB
dist/assets/hydrate.09f2daa6.js                    2.06 KiB / gzip: 0.96 KiB
dist/assets/plugin-vue_export-helper.21dcd24c.js   0.09 KiB / gzip: 0.10 KiB
dist/assets/Counter.island.d5166a1f.js             0.49 KiB / gzip: 0.34 KiB
dist/assets/Expandable.island.718a2566.js          0.81 KiB / gzip: 0.52 KiB
dist/assets/MediaQuery.island.fe4d450c.js          0.38 KiB / gzip: 0.29 KiB
dist/assets/Counter.island.9a7e7aed.css            0.05 KiB / gzip: 0.07 KiB
dist/assets/main.beb4e855.css                      0.75 KiB / gzip: 0.43 KiB
dist/assets/main.e47b13dd.js                       24.83 KiB / gzip: 10.35 KiB
dist/assets/Expandable.island.e8e34690.css         0.31 KiB / gzip: 0.20 KiB
dist/assets/runtime-dom.esm-bundler.19cc2f9d.js    59.27 KiB / gzip: 23.58 KiB
vite v2.9.13 building SSR bundle for production...
✓ 20 modules transformed.
dist/main.server.js   18.57 KiB
✨  Done in 2.70s.
  • Check output
dist
├── assets
│  ├── capri.ce1c56b3.svg
│  ├── Counter.island.9a7e7aed.css
│  ├── Counter.island.d5166a1f.js
│  ├── Expandable.island.718a2566.js
│  ├── Expandable.island.e8e34690.css
│  ├── hydrate.09f2daa6.js
│  ├── index.12a53772.js
│  ├── main.beb4e855.css
│  ├── main.e47b13dd.js
│  ├── MediaQuery.island.fe4d450c.js
│  ├── plugin-vue_export-helper.21dcd24c.js
│  └── runtime-dom.esm-bundler.19cc2f9d.js
├── index.html
├── preview
│  └── index.html
└── ssr-manifest.json

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.