Next.js Integration
Using ink-web with Next.js
Next.js Integration
This guide shows you how to use ink-web with Next.js, including how to handle client-side only rendering and edge runtime.
Installation
First, install the required dependencies:
npm install ink-web react xterm
# or
bun add ink-web react xtermUsing the Bundled Version
For Next.js, we recommend using the bundled version of ink-web as it's easier to configure:
'use client';
import { InkTerminalBox, Box, Text, useInput } from 'ink-web/bundled';
import 'ink-web/bundled/css';
import 'xterm/css/xterm.css';
import { useState } from 'react';
export function MyTerminal() {
const [input, setInput] = useState('');
useInput((inputChar, key) => {
if (key.return) {
console.log('User entered:', input);
setInput('');
} else if (key.backspace || key.delete) {
setInput((prev) => prev.slice(0, -1));
} else if (!key.ctrl && !key.meta && inputChar) {
setInput((prev) => prev + inputChar);
}
});
return (
<InkTerminalBox focus>
<Box flexDirection="column">
<Text color="green">Hello from Next.js!</Text>
<Text>
<Text color="cyan">> </Text>
<Text>{input}</Text>
<Text inverse> </Text>
</Text>
</Box>
</InkTerminalBox>
);
}Client-Side Only Rendering
Since ink-web relies on browser APIs (like document), you need to mark components using it with 'use client' directive at the top of the file.
Alternatively, you can use Next.js dynamic imports with SSR disabled:
import dynamic from 'next/dynamic';
const MyTerminal = dynamic(() => import('./components/MyTerminal'), {
ssr: false,
});
export default function Page() {
return (
<div>
<h1>My Terminal App</h1>
<MyTerminal />
</div>
);
}Edge Runtime
If you want to use Next.js Edge Runtime, you can configure it in your next.config.js:
/** @type {import('next').NextConfig} */
const config = {
reactStrictMode: true,
experimental: {
runtime: 'edge',
},
};
export default config;Or for specific pages/routes:
export const runtime = 'edge';
export default function Page() {
return <MyTerminal />;
}Common Issues
Module Not Found Errors
If you encounter module resolution errors during build, you may need to add some polyfills to your next.config.js:
/** @type {import('next').NextConfig} */
const config = {
webpack: (config) => {
config.resolve.fallback = {
...config.resolve.fallback,
fs: false,
net: false,
tls: false,
};
return config;
},
};
export default config;Hydration Errors
If you see hydration errors, make sure you're using the 'use client' directive or dynamic imports with ssr: false.