Repository navigation
JOPS 1.1.0: run a JOPS SPA inside Next.js, plus onPause(), tag props and multi-root layouts #2
arkwld
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Hi everyone 👋
JOPS 1.1.0 is out. In our last announcement we said we'd explore integrating JOPS with Next.js. That exploration is now a feature: a JOPS SPA can run inside a page of a Next.js (App Router) app, next to React.
⚛️ Next.js integration
JOPS doesn't replace React here; it works alongside it. Next.js keeps what it does best: server rendering, data, Route Handlers, its routing and the React ecosystem. JOPS adds class-based views with an Android-style lifecycle on the pages where your team prefers that model.
import JopsApp from "jops-core/nextjs", then<JopsApp app="/my-app/App.js" />. It loads the library once per page, adds the import map, and mounts the app into its own<div>./quotes), and JOPS owns the hash (/quotes#details?id=7). Next.js history state is kept in every entry JOPS writes, so Back/Forward work across both.public/and is served as-is. Tailwind CSS still picks up the classes used in JOPS files.Store,EventBus, history hooks). Coming back relaunches it and restores the screen from the hash.fetch().We tested this by migrating a complete quote-builder module of a Next.js CRM to JOPS: list, details, editor, status actions and new quote. Most of the fixes below came from that work.
Try it in a minute:
Pick 3. Next.js JOPS Embedded SPA: a Next.js project with a React-only page, a page hosting a JOPS SPA (mock login and a quotes list), and a Route Handler backend. To add JOPS to an existing Next.js app instead, see the README section "Next.js Integration".
🧩 New APIs
onPause(): called when another view comes to the front while this one stays alive. It pairs withonResume(), as on Android.this.props. For example,<Card jops src="/src/Card.js" title="Hi" item-id="7">gives{ title: "Hi", itemId: "7" }.get(id)searches all of them, and the newfind(id)returns every match.EventBus: withEventBus.subscribe(this, "event", callback), the subscription is removed automatically when the view is destroyed.mount()/unmount(). Standalone apps can also render into an element withdata-root="<id>".🛠️ Fixes (all apps, not only Next.js)
onclickhandlers in its own layout work.<Router>is reliably the default route.onResume()only when shown and only once, including views opened withnavigate().loadLayout()loads each layout once, andnew View("/layout.html")+addSubView()works.Element.set()/attr()/value()never throw. A wrong id logs a warning that names it.setStyle()accepts inline CSS with line breaks or quotes.npx jops-core init, "None" moved from choice 3 to choice 4. Scripts that pipe3intoinitnow get the Next.js template.find("some-id")with a string used to throw; it now returns an array ofElements.⬆️ How to upgrade
npm:
Since 1.0.15, the CLI tells you when a newer version is available.
CDN:
@latestserves 1.1.0. If you pin a version, use@1.1.0in both the import map and the script tag.Using Next.js? Tell us what you'd build with it in Ideas. Questions go to Q&A, and bugs to Issues.
Full changelog: CHANGELOG.md · Release: v1.1.0
All reactions