remix-utils
Advanced tools
Comparing version 2.5.0 to 2.6.0
import { ReactNode } from "react"; | ||
declare type Props = { | ||
/** | ||
* @deprecated Pass a function as children to avoid issues with client only | ||
* imported components | ||
*/ | ||
declare type DeprecatedProps = { | ||
children: ReactNode; | ||
fallback?: ReactNode; | ||
}; | ||
declare type Props = DeprecatedProps | { | ||
/** | ||
* You are encouraged to add a fallback that is the same dimensions | ||
* as the client rendered children. This will avoid content layout | ||
* shift which is disgusting | ||
*/ | ||
children: () => ReactNode; | ||
fallback?: ReactNode; | ||
}; | ||
/** | ||
@@ -16,3 +29,3 @@ * Render the children only after the JS has loaded client-side. Use an optional | ||
* <ClientOnly fallback={<FakeChart />}> | ||
* <Chart /> | ||
* {() => <Chart />} | ||
* </ClientOnly> | ||
@@ -19,0 +32,0 @@ * ); |
@@ -13,3 +13,3 @@ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime"; | ||
* <ClientOnly fallback={<FakeChart />}> | ||
* <Chart /> | ||
* {() => <Chart />} | ||
* </ClientOnly> | ||
@@ -20,3 +20,6 @@ * ); | ||
export function ClientOnly({ children, fallback = null }) { | ||
return useHydrated() ? _jsx(_Fragment, { children: children }, void 0) : _jsx(_Fragment, { children: fallback }, void 0); | ||
if (typeof children !== "function") { | ||
console.warn("[remix-utils] ClientOnly: Pass a function as children to avoid issues with client-only imported components"); | ||
} | ||
return useHydrated() ? (_jsx(_Fragment, { children: typeof children === "function" ? children() : children }, void 0)) : (_jsx(_Fragment, { children: fallback }, void 0)); | ||
} |
export * from "./server/body-parser"; | ||
export * from "./server/csrf"; | ||
export * from "./server/get-client-id-address"; | ||
export * from "./server/responses"; |
export * from "./server/body-parser"; | ||
export * from "./server/csrf"; | ||
export * from "./server/get-client-id-address"; | ||
export * from "./server/responses"; |
@@ -18,3 +18,3 @@ import { Session } from "@remix-run/server-runtime"; | ||
* let action: ActionFunction = async ({ request }) => { | ||
* let session = await getSession(request.headers.get("Cookie"); | ||
* let session = await getSession(request.headers.get("Cookie")); | ||
* await verifyAuthenticityToken(request, session); | ||
@@ -25,3 +25,3 @@ * // the request is authenticated and you can do anything here | ||
* let action: ActionFunction = async ({ request }) => { | ||
* let session = await getSession(request.headers.get("Cookie"); | ||
* let session = await getSession(request.headers.get("Cookie")); | ||
* await verifyAuthenticityToken(request, session, "csrfToken"); | ||
@@ -28,0 +28,0 @@ * // the request is authenticated and you can do anything here |
@@ -23,3 +23,3 @@ import { v4 as uuid } from "uuid"; | ||
* let action: ActionFunction = async ({ request }) => { | ||
* let session = await getSession(request.headers.get("Cookie"); | ||
* let session = await getSession(request.headers.get("Cookie")); | ||
* await verifyAuthenticityToken(request, session); | ||
@@ -30,3 +30,3 @@ * // the request is authenticated and you can do anything here | ||
* let action: ActionFunction = async ({ request }) => { | ||
* let session = await getSession(request.headers.get("Cookie"); | ||
* let session = await getSession(request.headers.get("Cookie")); | ||
* await verifyAuthenticityToken(request, session, "csrfToken"); | ||
@@ -33,0 +33,0 @@ * // the request is authenticated and you can do anything here |
import { ReactNode } from "react"; | ||
declare type Props = { | ||
/** | ||
* @deprecated Pass a function as children to avoid issues with client only | ||
* imported components | ||
*/ | ||
declare type DeprecatedProps = { | ||
children: ReactNode; | ||
fallback?: ReactNode; | ||
}; | ||
declare type Props = DeprecatedProps | { | ||
/** | ||
* You are encouraged to add a fallback that is the same dimensions | ||
* as the client rendered children. This will avoid content layout | ||
* shift which is disgusting | ||
*/ | ||
children: () => ReactNode; | ||
fallback?: ReactNode; | ||
}; | ||
/** | ||
@@ -16,3 +29,3 @@ * Render the children only after the JS has loaded client-side. Use an optional | ||
* <ClientOnly fallback={<FakeChart />}> | ||
* <Chart /> | ||
* {() => <Chart />} | ||
* </ClientOnly> | ||
@@ -19,0 +32,0 @@ * ); |
@@ -16,3 +16,3 @@ "use strict"; | ||
* <ClientOnly fallback={<FakeChart />}> | ||
* <Chart /> | ||
* {() => <Chart />} | ||
* </ClientOnly> | ||
@@ -23,4 +23,7 @@ * ); | ||
function ClientOnly({ children, fallback = null }) { | ||
return use_hydrated_1.useHydrated() ? jsx_runtime_1.jsx(jsx_runtime_1.Fragment, { children: children }, void 0) : jsx_runtime_1.jsx(jsx_runtime_1.Fragment, { children: fallback }, void 0); | ||
if (typeof children !== "function") { | ||
console.warn("[remix-utils] ClientOnly: Pass a function as children to avoid issues with client-only imported components"); | ||
} | ||
return use_hydrated_1.useHydrated() ? (jsx_runtime_1.jsx(jsx_runtime_1.Fragment, { children: typeof children === "function" ? children() : children }, void 0)) : (jsx_runtime_1.jsx(jsx_runtime_1.Fragment, { children: fallback }, void 0)); | ||
} | ||
exports.ClientOnly = ClientOnly; |
export * from "./server/body-parser"; | ||
export * from "./server/csrf"; | ||
export * from "./server/get-client-id-address"; | ||
export * from "./server/responses"; |
@@ -15,2 +15,3 @@ "use strict"; | ||
__exportStar(require("./server/csrf"), exports); | ||
__exportStar(require("./server/get-client-id-address"), exports); | ||
__exportStar(require("./server/responses"), exports); |
@@ -18,3 +18,3 @@ import { Session } from "@remix-run/server-runtime"; | ||
* let action: ActionFunction = async ({ request }) => { | ||
* let session = await getSession(request.headers.get("Cookie"); | ||
* let session = await getSession(request.headers.get("Cookie")); | ||
* await verifyAuthenticityToken(request, session); | ||
@@ -25,3 +25,3 @@ * // the request is authenticated and you can do anything here | ||
* let action: ActionFunction = async ({ request }) => { | ||
* let session = await getSession(request.headers.get("Cookie"); | ||
* let session = await getSession(request.headers.get("Cookie")); | ||
* await verifyAuthenticityToken(request, session, "csrfToken"); | ||
@@ -28,0 +28,0 @@ * // the request is authenticated and you can do anything here |
@@ -27,3 +27,3 @@ "use strict"; | ||
* let action: ActionFunction = async ({ request }) => { | ||
* let session = await getSession(request.headers.get("Cookie"); | ||
* let session = await getSession(request.headers.get("Cookie")); | ||
* await verifyAuthenticityToken(request, session); | ||
@@ -34,3 +34,3 @@ * // the request is authenticated and you can do anything here | ||
* let action: ActionFunction = async ({ request }) => { | ||
* let session = await getSession(request.headers.get("Cookie"); | ||
* let session = await getSession(request.headers.get("Cookie")); | ||
* await verifyAuthenticityToken(request, session, "csrfToken"); | ||
@@ -37,0 +37,0 @@ * // the request is authenticated and you can do anything here |
{ | ||
"name": "remix-utils", | ||
"version": "2.5.0", | ||
"version": "2.6.0", | ||
"license": "MIT", | ||
@@ -87,2 +87,3 @@ "engines": { | ||
"dependencies": { | ||
"is-ip": "^3.1.0", | ||
"type-fest": "^2.5.2", | ||
@@ -89,0 +90,0 @@ "uuid": "^8.3.2" |
@@ -17,3 +17,3 @@ # Remix Utils | ||
You can, optionally, provide a fallback component to be used on SSR. | ||
You can provide a fallback component to be used on SSR, and while optional, it's highly recommended to provide one to avoid content layout shift issues. | ||
@@ -26,3 +26,3 @@ ```tsx | ||
<ClientOnly fallback={<SimplerStaticVersion />}> | ||
<ComplexComponentNeedingBrowserEnvironment /> | ||
{() => <ComplexComponentNeedingBrowserEnvironment />} | ||
</ClientOnly> | ||
@@ -153,3 +153,3 @@ ); | ||
let session = await getSession(request.headers.get("Cookie")); | ||
await verifyAuthenticityToken(session); | ||
await verifyAuthenticityToken(request, session); | ||
// do something here | ||
@@ -532,2 +532,32 @@ return redirectBack(request, { fallback: "/fallback" }); | ||
### getClientIPAddress | ||
This function receives a Request or Headers objects and will try to get the IP address of the client (the user) who originated the request. | ||
```ts | ||
export let loader: LoaderFunction = async ({ request }) => { | ||
// using the request | ||
let ipAddress = getClientIPAddress(request); | ||
// or using the headers | ||
let ipAddress = getClientIPAddress(request.headers); | ||
}; | ||
``` | ||
If it can't find he ipAddress the return value will be `null`. Remember to check if it was able to find it before using it. | ||
The function uses the following list of headers, in order of prefecence: | ||
- X-Client-IP | ||
- X-Forwarded-For | ||
- CF-Connecting-IP | ||
- Fastly-Client-Ip | ||
- True-Client-Ip | ||
- X-Real-IP | ||
- X-Cluster-Client-IP | ||
- X-Forwarded | ||
- Forwarded-For | ||
- Forwarded | ||
When a header is found that contains a valid IP address, it will return without checking the other headers. | ||
### Responses | ||
@@ -534,0 +564,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
123720
82
2502
763
6
+ Addedis-ip@^3.1.0
+ Addedip-regex@4.3.0(transitive)
+ Addedis-ip@3.1.0(transitive)