https://github.com/lukasbombach/next-inline-script
https://github.com/lukasbombach/next-inline-script
Last synced: 3 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/lukasbombach/next-inline-script
- Owner: LukasBombach
- Created: 2022-07-21T10:48:28.000Z (almost 3 years ago)
- Default Branch: master
- Last Pushed: 2022-10-25T15:50:05.000Z (over 2 years ago)
- Last Synced: 2025-02-24T02:40:22.118Z (3 months ago)
- Language: JavaScript
- Size: 379 KB
- Stars: 3
- Watchers: 2
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# next-inline-script
> Check out the demo at [/apps/web](https://github.com/LukasBombach/next-inline-script/tree/master/apps/web)
Importing a file with `createInlineScript`
```tsx
// index.tsximport Head from "next/head";
import { createInlineScript } from "next-inline-script";const HelloWorld = createInlineScript(import("./helloWorld"));
export default function Page() {
return (
<>
Next Inline Script Demo
>
);
}
```which exports a function that can take props
```ts
// helloWorld.tsexport default function helloWorld(props: { message: string }): void {
console.log(props.message);
}
```will compile `helloWorld.ts` and render it **_inline_** in the `` section of your document
```html
(function helloWorld(props) {
console.log(props.message);
})({ message: "hello my message" });
```
## Why
This code gets executed before react or next js has loaded. It is not a silver bullet, inline JavaScript is render
blocking, but there are situations where this is critical. With this plugin you get a tool to design your loading
strategy and an execution order.- You need to initialize (complex) third party code
- You need exucute code with high priority
- You need to run code synchronously## Intellisense and TypeScript support
Using next js' built inline script features, you need to write code as a string, which makes debugging and
testing _really_ difficult. Using this plugin you get full IDE and TS integration, including type-safety of
the props of the generated React component and its data.## Features
- uses code splitting to separate your inline code from your main bundle, so your main bundle will not grow in size
- uses next's compiler with all its settings. Any plugin you use will also be available in the inline code
- code will be rendered at compile time, props will be injected at run time, so you can use dynamic data in your inline code
- testing with jest is completely possible, but I still need to document it## Documentaion
Add `next-inline-script/plugin` to your next config
```js
// next.config.jsconst withCompileToString = require("next-inline-script/plugin");
module.exports = withCompileToString({
reactStrictMode: true,
});
```Create a file that exports a function as default
```ts
// myScript.tsexport default function myScript(props: { message: string }): void {
console.log(props.message);
}
```Anywhere in your next js project pass an import statement to `createInlineScript` to create a react Component
that will render the compiled source of that file in a `` tag.```tsx
import { createInlineScript } from "next-inline-script";const MyScript = createInlineScript(import("./myScript"));
const MyComponent = () => <MyScript message="my message" />;
```Rendering `<MyScript message="my message" />` will give you this code:
```html
<script>
(function myScript(props) {
console.log(props.message);
})({ message: "hello my message" });```
Your code will get transpiled and inlined and the props of the JSX declaration (`message="my message"`) will
be stringified using `JSON.stringify` and passed to your function.This means any data that can be serialized with `JSON.stringify` can be passed to the your code.
## Compile time and Run Time
Your code will be transpiled at compile time
```js
(function myScript(props) {
console.log(props.message);
});
```but the props will get rendered at run time
```js
(/* function myScript(props) {
console.log(props.message);
} */)({ message: "hello my message" });
```This has a big advantage:
Lets say you need to initialze some third party library, like ads, tracking or consent. For the initilization you
often need to use data that you do not know at compile time, but only at run time. By passing in that data as props
instead of hard-coded values in your script, you can _have your cake and eat it too_!## State
### Quirks
You need to pass an import statement to the `createInlineScript` function. This is to enable IDE and TS support,
but this also comes with an _obligation_ to do this, you can't just us a path as a string, for instance.You also _need_ a default export which has to be a function. This issue can be resolved, which will happen at
some point.### Test suite
While this repo does not contain unit-tests yet, this plugin is implicitly unit-tested and battle tested at [t-online.de](https://t-online.de),
Germany's largest news website with millions of users. A test suit will follow as I complete the library.