├── packages ├── example │ ├── .gitignore │ ├── src │ │ ├── components │ │ │ ├── Text │ │ │ │ ├── index.tsx │ │ │ │ ├── Text.module.scss │ │ │ │ └── Text.tsx │ │ │ ├── Button │ │ │ │ ├── index.tsx │ │ │ │ ├── Button.module.scss │ │ │ │ └── Button.tsx │ │ │ ├── Counter │ │ │ │ ├── index.tsx │ │ │ │ ├── Counter.module.scss │ │ │ │ ├── Counter.tsx │ │ │ │ └── Counter.client.tsx │ │ │ ├── Layout │ │ │ │ ├── index.tsx │ │ │ │ ├── Layout.module.scss │ │ │ │ └── Layout.tsx │ │ │ ├── Toggler │ │ │ │ ├── index.tsx │ │ │ │ ├── Toggler.module.scss │ │ │ │ ├── Toggler.client.tsx │ │ │ │ └── Toggler.tsx │ │ │ ├── Navigation │ │ │ │ ├── index.tsx │ │ │ │ ├── Navigation.module.scss │ │ │ │ └── Navigation.tsx │ │ │ ├── ReactComponent │ │ │ │ ├── index.tsx │ │ │ │ └── ReactComponent.tsx │ │ │ └── Image │ │ │ │ ├── index.ts │ │ │ │ ├── CssImage.module.scss │ │ │ │ ├── Image.tsx │ │ │ │ ├── CssImage.tsx │ │ │ │ └── image.svg │ │ └── pages │ │ │ ├── index.client.tsx │ │ │ ├── tests │ │ │ ├── index.client.tsx │ │ │ ├── nested.client.tsx │ │ │ ├── react.page.tsx │ │ │ ├── nested.page.tsx │ │ │ ├── data.page.tsx │ │ │ └── index.page.tsx │ │ │ ├── dynamic │ │ │ ├── [initialCount].client.tsx │ │ │ └── [initialCount].page.tsx │ │ │ ├── _document.page.tsx │ │ │ └── index.page.tsx │ ├── next-env.d.ts │ ├── types │ │ └── assets.d.ts │ ├── public │ │ └── favicon.ico │ ├── README.md │ ├── .eslintrc │ ├── next.config.js │ ├── tsconfig.json │ └── package.json └── next-client-script │ ├── types │ └── next-transpile-modules.d.ts │ ├── src │ ├── ClientScriptsByPath.tsx │ ├── ClientWidget.tsx │ ├── ClientScript.tsx │ ├── initWidgets.tsx │ └── withClientScripts.tsx │ ├── .eslintrc │ ├── tsconfig.json │ ├── rollup.config.js │ └── package.json ├── .gitignore ├── CHANGELOG.md ├── package.json ├── .github └── workflows │ └── main.yml ├── LICENSE └── README.md /packages/example/.gitignore: -------------------------------------------------------------------------------- 1 | .vercel -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | dist 4 | .next -------------------------------------------------------------------------------- /packages/example/src/components/Text/index.tsx: -------------------------------------------------------------------------------- 1 | export {default} from './Text'; 2 | -------------------------------------------------------------------------------- /packages/example/src/components/Button/index.tsx: -------------------------------------------------------------------------------- 1 | export {default} from './Button'; 2 | -------------------------------------------------------------------------------- /packages/example/src/components/Counter/index.tsx: -------------------------------------------------------------------------------- 1 | export {default} from './Counter'; 2 | -------------------------------------------------------------------------------- /packages/example/src/components/Layout/index.tsx: -------------------------------------------------------------------------------- 1 | export {default} from './Layout'; 2 | -------------------------------------------------------------------------------- /packages/example/src/components/Toggler/index.tsx: -------------------------------------------------------------------------------- 1 | export {default} from './Toggler'; 2 | -------------------------------------------------------------------------------- /packages/example/src/components/Navigation/index.tsx: -------------------------------------------------------------------------------- 1 | export {default} from './Navigation'; 2 | -------------------------------------------------------------------------------- /packages/example/src/components/ReactComponent/index.tsx: -------------------------------------------------------------------------------- 1 | export {default} from './ReactComponent'; 2 | -------------------------------------------------------------------------------- /packages/next-client-script/types/next-transpile-modules.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'next-transpile-modules'; 2 | -------------------------------------------------------------------------------- /packages/example/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /packages/example/types/assets.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.svg' { 2 | const content: string; 3 | export default content; 4 | } 5 | -------------------------------------------------------------------------------- /packages/example/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amannn/next-client-script/HEAD/packages/example/public/favicon.ico -------------------------------------------------------------------------------- /packages/example/src/components/Image/index.ts: -------------------------------------------------------------------------------- 1 | export {default} from './Image'; 2 | export {default as CssImage} from './CssImage'; 3 | -------------------------------------------------------------------------------- /packages/example/src/components/Image/CssImage.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | width: 25px; 3 | height: 25px; 4 | background: url('./image.svg'), #ddd; 5 | } 6 | -------------------------------------------------------------------------------- /packages/next-client-script/src/ClientScriptsByPath.tsx: -------------------------------------------------------------------------------- 1 | type ClientScriptsByPath = { 2 | [path: string]: string; 3 | }; 4 | 5 | export default ClientScriptsByPath; 6 | -------------------------------------------------------------------------------- /packages/example/src/components/Image/Image.tsx: -------------------------------------------------------------------------------- 1 | import image from './image.svg'; 2 | 3 | export default function Image() { 4 | return ; 5 | } 6 | -------------------------------------------------------------------------------- /packages/example/src/components/Image/CssImage.tsx: -------------------------------------------------------------------------------- 1 | import styles from './CssImage.module.scss'; 2 | 3 | export default function CssImage() { 4 | return
; 5 | } 6 | -------------------------------------------------------------------------------- /packages/example/src/pages/index.client.tsx: -------------------------------------------------------------------------------- 1 | import initWidgets from 'next-client-script/dist/initWidgets'; 2 | import Counter from 'components/Counter/Counter.client'; 3 | 4 | initWidgets([Counter]); 5 | -------------------------------------------------------------------------------- /packages/example/src/pages/tests/index.client.tsx: -------------------------------------------------------------------------------- 1 | import initWidgets from 'next-client-script/dist/initWidgets'; 2 | import Toggler from 'components/Toggler/Toggler.client'; 3 | 4 | initWidgets([Toggler]); 5 | -------------------------------------------------------------------------------- /packages/example/src/pages/tests/nested.client.tsx: -------------------------------------------------------------------------------- 1 | import initWidgets from 'next-client-script/dist/initWidgets'; 2 | import Counter from 'components/Counter/Counter.client'; 3 | 4 | initWidgets([Counter]); 5 | -------------------------------------------------------------------------------- /packages/example/src/pages/dynamic/[initialCount].client.tsx: -------------------------------------------------------------------------------- 1 | import initWidgets from 'next-client-script/dist/initWidgets'; 2 | import Counter from 'components/Counter/Counter.client'; 3 | 4 | initWidgets([Counter]); 5 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 0.1.0 4 | 5 | Compatibility with `next@^9.5.0`. Older versions are no longer supported. 6 | 7 | ## 0.0.6 8 | 9 | First working version that's compatible with `next@^9.4.0`. 10 | -------------------------------------------------------------------------------- /packages/example/src/components/Button/Button.module.scss: -------------------------------------------------------------------------------- 1 | .button { 2 | background-color: #4572e4; 3 | color: white; 4 | padding: 10px 20px; 5 | border: none; 6 | border-radius: 5px; 7 | font-size: 14px; 8 | } 9 | -------------------------------------------------------------------------------- /packages/example/src/components/Text/Text.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | &_title { 3 | font-size: 32px; 4 | } 5 | 6 | &_body { 7 | font-size: 16px; 8 | opacity: 0.8; 9 | line-height: 1.5; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/next-client-script/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["molindo/react", "molindo/typescript"], 3 | "env": { 4 | "node": true 5 | }, 6 | "globals": { 7 | "CLIENT_SCRIPTS_BY_PATH": false 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/example/src/components/Toggler/Toggler.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | background: #eee; 3 | padding: 10px; 4 | 5 | &_toggled { 6 | background: #ddd; 7 | } 8 | } 9 | 10 | .button { 11 | display: block; 12 | } 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "lint": "cd packages/next-client-script && yarn lint && cd ../example && yarn lint" 5 | }, 6 | "workspaces": [ 7 | "packages/example", 8 | "packages/next-client-script" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /packages/example/README.md: -------------------------------------------------------------------------------- 1 | # next-client-script example 2 | 3 | ## Test plan 4 | 5 | - Development 6 | - Script loads and executes 7 | - Reloads the page on change 8 | - Production 9 | - Script loads and executes 10 | - Script has immutable caching header 11 | -------------------------------------------------------------------------------- /packages/example/src/components/Layout/Layout.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | padding: 20px; 3 | font-family: Avenir, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, 4 | Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; 5 | } 6 | 7 | .children { 8 | margin-top: 40px; 9 | } 10 | -------------------------------------------------------------------------------- /packages/example/src/components/Image/image.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/example/src/components/Counter/Counter.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | display: flex; 3 | align-items: center; 4 | } 5 | 6 | .label { 7 | margin: 0; 8 | font-size: 16px; 9 | } 10 | 11 | .count { 12 | display: inline-block; 13 | font-weight: bold; 14 | min-width: 25px; 15 | } 16 | 17 | .button { 18 | margin-left: 20px; 19 | } 20 | -------------------------------------------------------------------------------- /packages/example/src/components/ReactComponent/ReactComponent.tsx: -------------------------------------------------------------------------------- 1 | import Button from 'components/Button'; 2 | 3 | export default function ReactComponent() { 4 | function onClick() { 5 | alert('This was triggered by React from a hydrated client.'); 6 | } 7 | 8 | return ( 9 |
10 | 11 |
12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /packages/example/src/components/Navigation/Navigation.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | display: flex; 3 | padding: 20px 30px; 4 | background-color: #f0f0f0; 5 | border-radius: 8px; 6 | } 7 | 8 | .internal { 9 | margin-right: auto; 10 | 11 | > *:not(:first-child) { 12 | margin-left: 20px; 13 | } 14 | } 15 | 16 | .link { 17 | color: inherit; 18 | text-decoration: none; 19 | } 20 | -------------------------------------------------------------------------------- /packages/example/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["molindo/typescript", "molindo/react"], 3 | "env": { 4 | "browser": true, 5 | "node": true 6 | }, 7 | "rules": { 8 | "react/react-in-jsx-scope": "OFF" 9 | }, 10 | "overrides": [ 11 | { 12 | "files": ["*.client.tsx"], 13 | "rules": { 14 | "css-modules/no-unused-class": "OFF" 15 | } 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /packages/example/src/pages/tests/react.page.tsx: -------------------------------------------------------------------------------- 1 | import Layout from 'components/Layout'; 2 | import ReactComponent from 'components/ReactComponent'; 3 | import Text from 'components/Text'; 4 | 5 | export default function ReactPage() { 6 | return ( 7 | 8 | 9 | React on the client side 10 | 11 | 12 | 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /packages/example/src/pages/_document.page.tsx: -------------------------------------------------------------------------------- 1 | import ClientScript from 'next-client-script/dist/ClientScript'; 2 | import Document, {Html, Head, Main, NextScript} from 'next/document'; 3 | 4 | export default class CustomDocument extends Document { 5 | public render() { 6 | return ( 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/example/src/components/Button/Button.tsx: -------------------------------------------------------------------------------- 1 | import {DetailedHTMLProps, ButtonHTMLAttributes} from 'react'; 2 | import styles from './Button.module.scss'; 3 | 4 | export default function Button({ 5 | className, 6 | ...rest 7 | }: DetailedHTMLProps< 8 | ButtonHTMLAttributes, 9 | HTMLButtonElement 10 | >) { 11 | return ( 12 |