Hi, it's Takuya.
I'm publishing YouTube content, sharing my dev workflows.
Want a side-by-side preview in a terminal app
For web coding tutorials, it'd be great to show your coding and output side-by-side.
Typically, you would do that by simply arranging two windows: An editor and a browser.
But that's annoying because every time you make a tutorial, you have to align the windows side-by-side.
Hyper, a terminal app built with web standards, once had a built-in webview feature:
As you can see above, it displays a preview on the right side of the terminal window.
It looks pretty neat.
So, you can make tutorials without having a separate window for preview.
But it looks like the feature has been removed for security reasons:
It was 3 years ago, a quite old issue.
I understand the risk of loading web pages in Electron apps.
However, webview
of the recent Electron prohibits NodeJS integration by default. So, I think it's safe to embed in Hyper, especially when you understand what you do.
Hacking Hyper to get back the built-in webview feature
So, I decided to get that feature back to Hyper, and successfully did it.
Here is how it looks like:
Demo video:
How to build
I've made built-in-webview
branch for the hack:
https://github.com/craftzdog/hyper/tree/built-in-webview
Clone this repo and built it yourself as following.
npm i npm run dev # On another terminal session npm run app
How to use
Split the window right by pressing Cmd-D
.
Then, type echo <URL-to-open>
and hit Return
.
Click the URL in the terminal.
Then, the pane becomes a webview that loads the URL.
How I hacked Hyper
Check out the diffs
First, you have to allow webview
tags in app/ui/window.ts
:
const winOpts: BrowserWindowConstructorOptions = { minWidth: 370, minHeight: 190, backgroundColor: toElectronBackgroundColor(cfg.backgroundColor || '#000'), titleBarStyle: 'hiddenInset', title: 'Hyper.app', // we want to go frameless on Windows and Linux frame: process.platform === 'darwin', transparent: process.platform === 'darwin', icon, show: Boolean(process.env.HYPER_DEBUG || process.env.HYPERTERM_DEBUG || isDev), acceptFirstMouse: true, webPreferences: { nodeIntegration: true, navigateOnDragDrop: true, enableRemoteModule: true, - contextIsolation: false + contextIsolation: false, + webviewTag: true }, ...options_ };
Hyper partially remains the old implementations. You can reuse them.
The terminal component already has url
prop.
You can display webview
when the component has url
prop.
In lib/components/term.tsx
, change the terminal component class like so:
@@ -430,18 +436,35 @@ export default class Term extends React.PureComponent<TermProps> { style={{padding: this.props.padding}} onMouseUp={this.onMouseUp} > - {this.props.customChildrenBefore} - <div ref={this.onTermWrapperRef} className="term_fit term_wrapper" /> - {this.props.customChildren} - {this.props.search ? ( - <SearchBox - search={this.search} - next={this.searchNext} - prev={this.searchPrevious} - close={this.closeSearchBox} + {this.props.url ? ( + <webview + src={this.props.url} + style={{ + background: '#fff', + position: 'absolute', + top: 0, + left: 0, + display: 'inline-flex', + width: '100%', + height: '100%' + }} /> ) : ( - '' + <> + {this.props.customChildrenBefore} + <div ref={this.onTermWrapperRef} className="term_fit term_wrapper" /> + {this.props.customChildren} + {this.props.search ? ( + <SearchBox + search={this.search} + next={this.searchNext} + prev={this.searchPrevious} + close={this.closeSearchBox} + /> + ) : ( + '' + )} + </> )} <style jsx global>{`
And, change the URL click handler to dispatch an action instead of opening up the page in an external browser:
@@ -160,7 +160,13 @@ export default class Term extends React.PureComponent<TermProps> { this.term.loadAddon( new WebLinksAddon( (event: MouseEvent | undefined, uri: string) => { - if (shallActivateWebLink(event)) void shell.openExternal(uri); + // if (shallActivateWebLink(event)) void shell.openExternal(uri); + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + store.dispatch({ + type: 'SESSION_URL_SET', + uid: props.uid, + url: uri + }); }, { // prevent default electron link handling to allow selection, e.g. via double-click
In lib/reducers/sessions.ts
, add the reducer for SESSION_URL_SET
like so:
@@ -11,7 +11,8 @@ import { SESSION_SET_XTERM_TITLE, SESSION_SET_CWD, SESSION_SEARCH, - SESSION_SEARCH_CLOSE + SESSION_SEARCH_CLOSE, + SESSION_URL_SET } from '../constants/sessions'; import {sessionState, session, Mutable, ISessionReducer} from '../hyper'; @@ -129,6 +130,9 @@ const reducer: ISessionReducer = (state = initialState, action) => { } return state; + case SESSION_URL_SET: + return state.setIn(['sessions', action.uid, 'url'], action.url); + default: return state; }
It works like a charm!
Follow me online
- Check out my app called Inkdrop - A Markdown note-taking app
- Subscribe Newsletter http://eepurl.com/dNgJo6
- Twitter https://twitter.com/inkdrop_app
- YouTube channel https://youtube.com/c/devaslife
- Blog https://blog.inkdrop.app/
- Discord community https://discord.gg/QfsG5Kj
- Instagram https://instagram.com/craftzdog
Top comments (18)
Was looking for this after I saw the YouTube video and it is awesome, will do this and see how it goes, coding on terminal hard tho 😂
yeah lol. hope it's helpful for your videos
Seguir seu tutorial, mas quando rodo o comando "npm run app" ou "yarn run app" recebo esse erro. Utilizo ubuntu linux.
Error launching app
Unable to find Electron app at /home/antonio/hyper/target
Cannot find module '/home/antonio/hyper/target'
Require stack:
- /home/antonio/hyper/node_modules/electron/dist/resources/default_app.asar/main.js
for who ever fail to compile try to disable typescript check
with put
// @ts-nocheck
at the top levelto all over error file that printed when run dev, because it used old version and we just want the feature so i think is fair. Then after notice run dev got no error u safe to go with run app. Hopes help y'all have a nice day!
And for windows it should works fine or you can build by ur self it maybe just a little confusing for some newcomers but do a little bit research and it will solved.
Hi Takuya, I came across your post and did as your guide but I had trouble with the node version which crashed the build step. Could you tell me the exactly version of nodejs for your hyper fork. Thanks
I have problems with the dependencies as I have 23 vulnerabilities and I tried to solve them but I could not, someone could or there is a tutorial on youtube?

Hello Mr. Takuya,
please tell me how can I compile this exe for Windows?
Please help me....
I could compile it on mac node v: 18 everything works grea
t
What version of node did you use?
Did you ever figure out how to get it on windows?
you can make a bat script that runs the command that runs the hyper terminal. that's the closest i have got
Dev mode works, but the error "store" is not found. I also get an error trying to package the binary file.
(window as any).store did the trick for me
hello,
for windows ?
did you get it to work for windows?
can someone create a tutorial how to setup this pls
Did anyone have trying it on Ubuntu and works? Wondering how to make it work since I can't install it properly, got node-pty error
What was the node version when the changes were node. Cannot get it running.