diff --git a/data/en/snippets/remixing-remix-submission.mdx b/data/en/snippets/remixing-remix-submission.mdx
new file mode 100644
index 00000000..2d558ea6
--- /dev/null
+++ b/data/en/snippets/remixing-remix-submission.mdx
@@ -0,0 +1,182 @@
+---
+heading: 'Remixing remix submission'
+title: 'Standardized hook for handling route submission in a Remix app'
+date: '2023-09-04'
+type: 'Remix'
+draft: false
+summary: 'A custom hook to handle in-route-submission in a Remix app'
+tags: [tag1, tag2, tag3, tag4]
+---
+
+import Twemoji from './Twemoji.tsx'
+
+I have been working with [Remix](https://remix.run) for a while now and I love it.
+Here is a custom hook I use to handle in-route-submission in my Remix apps.
+
+````ts:use-route-submission.ts
+import { useActionData, useNavigation, useSubmit } from '@remix-run/react'
+import { useEffect } from 'react'
+import { parseSubmissionData } from '~/utils/object'
+import { useIndexRouteDetector } from './use-index-route-detector'
+import type { RouteSubmission, RouteSubmissionInput, SubmitData } from '~/types/hooks'
+
+/**
+ * Submit data to the current route from any nested element.
+ * Prefer this over `useSubmitFetcher` as it allows the `actionData` from `useActionData` hook can be accessed from any nested component in the route no matter how deep it is.
+ *
+ * @param input - `object` - The input to use for the route submission
+ * @param [input._action] - The `_action` to use for the route submission, it will be added to submit data
+ * @param [input.onSubmitted] - A callback to run when the route submission is submitted
+ * @returns RouteSubmission
+ * @example
+ * ```tsx
+ * import { useRouteSubmission } from '~/hooks'
+ *
+ * export function MyComponent() {
+ * // An `_action` param should be added to differentiate between multiple submissions
+ * let [submit, submitting, submitData] = useRouteSubmission({ _action: 'myAction' })
+ * // or let {submit, submitting, submitData} = useRouteSubmission({ _action: 'myAction' })
+ *
+ * let handleClick = () => submit({ name: 'John Doe' })
+ * let loading = submitting
+ *
+ * return (
+ *
+ * )
+ * }
+ *```
+ */
+export function useRouteSubmission(input: RouteSubmissionInput): RouteSubmission {
+ let _submit = useSubmit()
+ let navigation = useNavigation()
+ let isIndexRoute = useIndexRouteDetector()
+ let actionData = useActionData()
+
+ let { _action, onSubmitted } = input || {}
+ let submitData = parseSubmissionData(navigation)
+ let isActionMatched = submitData?._action === _action
+
+ useEffect(() => {
+ if (isActionMatched && navigation.state === 'loading') {
+ onSubmitted?.(submitData, actionData)
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [navigation.state])
+
+ let submit = (data: SubmitData = {}) => {
+ let actionURL = window.location.pathname
+ _submit(
+ { data: JSON.stringify({ ...data, _action }) },
+ {
+ action: isIndexRoute ? `${actionURL}?index` : actionURL,
+ method: 'post',
+ replace: true,
+ }
+ )
+ }
+ let submitting = isActionMatched && navigation.state === 'submitting'
+
+ return Object.defineProperty({ submit, submitting, submitData }, Symbol.iterator, {
+ enumerable: false,
+ value: function* () {
+ yield submit
+ yield submitting
+ yield submitData
+ },
+ }) as RouteSubmission
+}
+````
+
+The utils used in the hook are:
+
+```ts:object.ts
+import type { useNavigation } from '@remix-run/react'
+import type {SubmitDataWithAction} from '~/types/hooks'
+
+/**
+ * Get the submitted data of a submission
+ *
+ * @param navigation - The current page navigation returned from `useNavigation` hook
+ * @example
+ * let data = parseSubmissionData(transition)
+ */
+export function parseSubmissionData(
+ navigation: ReturnType,
+): SubmitDataWithAction {
+ let formData = navigation?.formData
+ if (!formData) return null
+ return JSON.parse((Object.fromEntries(formData) as any).data)
+}
+```
+
+And
+
+```ts:use-index-route-detector.ts
+import { useLocation, useMatches } from '@remix-run/react'
+
+export function useIndexRouteDetector() {
+ let matches = useMatches()
+ let location = useLocation()
+ let match = matches.find(({ pathname }) => pathname === location.pathname)
+ if (match) {
+ return !!match.id.match(/\/index$/) || match.id === 'root'
+ }
+ return false
+}
+```
+
+And the types used in the hook are:
+
+```ts:hooks.ts
+export type RouteSubmissionInput = {
+ _action: string
+ onSubmitted?: (
+ submitData: SubmitDataWithAction,
+ actionData: { [key: string]: any },
+ ) => void
+}
+
+export type SubmitData = {
+ [key: string]: any
+}
+
+export type SubmitDataWithAction = {
+ _action?: string
+ [key: string]: any
+}
+
+type SubmitFunction = (data?: SubmitData) => void
+
+export type RouteSubmission = {
+ submit: SubmitFunction
+ submitting: boolean
+ submitData: SubmitDataWithAction
+} & [SubmitFunction, boolean, SubmitDataWithAction]
+```
+
+Example usage:
+
+```tsx:example.tsx
+import { Button } from '~/components/button'
+import { useRouteSubmission } from '~/hooks/use-route-submission'
+
+export function SaveProject() {
+ // An `_action` param should be added to differentiate between multiple submissions
+ let [submit, submitting] = useRouteSubmission({ _action: 'SAVE_DATA' })
+ // or let {submit, submitting} = useRouteSubmission({ _action: 'SAVE_DATA' })
+
+ function save() {
+ submit({ name: 'John Doe' })
+ }
+
+ return (
+
+ )
+}
+```
+
+Happy submitting!