remix-utils
Advanced tools
Comparing version 2.2.0 to 2.3.0
export * from "./react/client-only"; | ||
export * from "./react/csrf"; | ||
export * from "./react/external-scripts"; | ||
export * from "./react/outlet"; | ||
@@ -7,2 +8,3 @@ export * from "./react/revalidate-link"; | ||
export * from "./react/use-revalidate"; | ||
export * from "./react/use-route-data"; | ||
export * from "./react/use-should-hydrate"; |
export * from "./react/client-only"; | ||
export * from "./react/csrf"; | ||
export * from "./react/external-scripts"; | ||
export * from "./react/outlet"; | ||
@@ -7,2 +8,3 @@ export * from "./react/revalidate-link"; | ||
export * from "./react/use-revalidate"; | ||
export * from "./react/use-route-data"; | ||
export * from "./react/use-should-hydrate"; |
@@ -13,3 +13,3 @@ import { ReactNode } from "react"; | ||
* ```tsx | ||
* let { csrf } = useRouteData<{ csrf: string }>(); | ||
* let { csrf } = useLoaderData<{ csrf: string }>(); | ||
* return ( | ||
@@ -16,0 +16,0 @@ * <AuthenticityTokenProvider token={csrf}> |
@@ -8,3 +8,3 @@ import { jsx as _jsx } from "react/jsx-runtime"; | ||
* ```tsx | ||
* let { csrf } = useRouteData<{ csrf: string }>(); | ||
* let { csrf } = useLoaderData<{ csrf: string }>(); | ||
* return ( | ||
@@ -11,0 +11,0 @@ * <AuthenticityTokenProvider token={csrf}> |
@@ -43,2 +43,5 @@ export let bodyParser = { | ||
async toJSON(request) { | ||
if (request.headers.get("Content-Type") === "application/json") { | ||
return request.json(); | ||
} | ||
let params = await this.toSearchParams(request); | ||
@@ -45,0 +48,0 @@ return Object.fromEntries(params.entries()); |
export * from "./react/client-only"; | ||
export * from "./react/csrf"; | ||
export * from "./react/external-scripts"; | ||
export * from "./react/outlet"; | ||
@@ -7,2 +8,3 @@ export * from "./react/revalidate-link"; | ||
export * from "./react/use-revalidate"; | ||
export * from "./react/use-route-data"; | ||
export * from "./react/use-should-hydrate"; |
@@ -15,2 +15,3 @@ "use strict"; | ||
__exportStar(require("./react/csrf"), exports); | ||
__exportStar(require("./react/external-scripts"), exports); | ||
__exportStar(require("./react/outlet"), exports); | ||
@@ -20,2 +21,3 @@ __exportStar(require("./react/revalidate-link"), exports); | ||
__exportStar(require("./react/use-revalidate"), exports); | ||
__exportStar(require("./react/use-route-data"), exports); | ||
__exportStar(require("./react/use-should-hydrate"), exports); |
@@ -13,3 +13,3 @@ import { ReactNode } from "react"; | ||
* ```tsx | ||
* let { csrf } = useRouteData<{ csrf: string }>(); | ||
* let { csrf } = useLoaderData<{ csrf: string }>(); | ||
* return ( | ||
@@ -16,0 +16,0 @@ * <AuthenticityTokenProvider token={csrf}> |
@@ -11,3 +11,3 @@ "use strict"; | ||
* ```tsx | ||
* let { csrf } = useRouteData<{ csrf: string }>(); | ||
* let { csrf } = useLoaderData<{ csrf: string }>(); | ||
* return ( | ||
@@ -14,0 +14,0 @@ * <AuthenticityTokenProvider token={csrf}> |
@@ -46,2 +46,5 @@ "use strict"; | ||
async toJSON(request) { | ||
if (request.headers.get("Content-Type") === "application/json") { | ||
return request.json(); | ||
} | ||
let params = await this.toSearchParams(request); | ||
@@ -48,0 +51,0 @@ return Object.fromEntries(params.entries()); |
{ | ||
"name": "remix-utils", | ||
"version": "2.2.0", | ||
"version": "2.3.0", | ||
"license": "MIT", | ||
@@ -5,0 +5,0 @@ "engines": { |
107
README.md
@@ -161,4 +161,63 @@ # Remix Utils | ||
### ExternalScripts | ||
If you need to load different external scripts on certain routes, you can use the `ExternalScripts` component together with the `ExternalScriptsFunction` type. | ||
In the route you want to load the script add a `handle` export with a scripts method, this method should implement the `ExternalScriptsFunction` type. | ||
```ts | ||
// create the scripts function with the correct type | ||
let scripts: ScriptsFunction = () => { | ||
return [ | ||
{ | ||
src: "https://code.jquery.com/jquery-3.6.0.min.js", | ||
integrity: "sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=", | ||
crossOrigin: "anonymous", | ||
}, | ||
]; | ||
}; | ||
// and export it through the handle, you could also create it inline here | ||
// if you don't care about the type | ||
export let handle = { scripts }; | ||
``` | ||
Then, in the root route, add the `ExternalScripts` component together with the Remix Scripts component, usually inside a Document component. | ||
```tsx | ||
import { Links, LiveReload, Meta, Scripts, ScrollRestoration } from "remix"; | ||
import { ExternalScripts } from "remix-utils"; | ||
type Props = { children: React.ReactNode; title?: string }; | ||
export function Document({ children, title }: Props) { | ||
return ( | ||
<html lang="en"> | ||
<head> | ||
<meta charSet="utf-8" /> | ||
<meta name="viewport" content="width=device-width,initial-scale=1" /> | ||
{title ? <title>{title}</title> : null} | ||
<Meta /> | ||
<Links /> | ||
</head> | ||
<body> | ||
{children} | ||
<ScrollRestoration /> | ||
<ExternalScripts /> | ||
<Scripts /> | ||
{process.env.NODE_ENV === "development" && <LiveReload />} | ||
</body> | ||
</html> | ||
); | ||
} | ||
``` | ||
Now, any script you defined in the ScriptsFunction will be added to the HTML together with a `<link rel="preload">` before it. | ||
> Tip: You could use it together with useShouldHydrate to disable Remix scripts in certain routes but still load scripts for analytics or small features that need JS but don't need the full app JS to be enabled. | ||
### Outlet & useParentData | ||
> This features is not built-in into Remix so it's marked as deprecated here. The features will be removed in v3 of Remix Utils. | ||
This wrapper of the Remix Outlet component lets you pass an optional `data` prop, then using the `useParentData` hook, you can access that data. | ||
@@ -249,2 +308,46 @@ | ||
### useRouteData | ||
This hook lets you access the data of any route in the current page. This can include child or parent routes. | ||
To use it, call `useRouteData` in your component and pass the route path as a string. As an example, if you had the following routes: | ||
``` | ||
routes/articles/$slug.tsx | ||
routes/articles/index.tsx | ||
routes/articles.tsx | ||
``` | ||
Then you need to pass `useRouteData("/articles")` to get the data of `routes/articles.tsx` and `useRouteData("/articles/")` to get the data of `routes/articles/index.tsx`. | ||
```ts | ||
let parentData = useRouteData("/articles"); | ||
let indexData = useRouteData("/articles/"); | ||
``` | ||
If the pathname is dynamic as with the `routes/articles/$slug.tsx` route, you can attach and ID to the route using the `handle` export, and then use that ID in the `useRouteData` hook. | ||
```ts | ||
// inside routes/articles/$slug.tsx | ||
export let handle = { id: "article-show" }; // the ID can be anything | ||
``` | ||
```tsx | ||
// inside any other route | ||
import { useRouteData } from "remix-utils"; | ||
export default function Screen() { | ||
let data = useRouteData("article-show"); | ||
// use data here | ||
} | ||
``` | ||
The `useRouteData` hook receives a generic to be used as the type of the route data. Because the route may not be found the return type is `Data | undefined`. This means if you do the following: | ||
```ts | ||
let data = useRouteData<ArticleShowData>("article-show"); | ||
``` | ||
The type of `data` will be `ArticleShowData | undefined`, so you will need to check if it's not undefined before being able to use it. | ||
### useShouldHydrate | ||
@@ -331,2 +434,4 @@ | ||
> A better version of this features is supported out of the box by Remix. It's recommended to use `await request.formData()` instead. | ||
This function receives the whole request and returns a promise with an instance of `URLSearchParams`, and the request's body is already parsed. | ||
@@ -386,2 +491,4 @@ | ||
> This features is not built-in into Remix so it's marked as deprecated here. The features will be removed in v3 of Remix Utils. | ||
This function is a typed version of the `json` helper provided by Remix. It accepts a generic with the type of data you are going to send in the response. | ||
@@ -388,0 +495,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
101206
74
1985
626