Skip to content

Commit

Permalink
Refactor navigation APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
amannn committed Aug 27, 2024
1 parent 0d89722 commit 762465b
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 122 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React, {ComponentProps, ReactElement, forwardRef, useMemo} from 'react';
import useLocale from '../../react-client/useLocale';
import {
receiveRoutingConfig,
RoutingConfigLocalizedNavigation
} from '../../routing/config';
import {Locales, Pathnames} from '../../routing/types';
import {ParametersExceptFirst} from '../../shared/types';
import {
LocalizedNavigationRoutingConfigInput,
receiveLocalizedNavigationRoutingConfig
} from '../shared/config';
import {
compileLocalizedPathname,
getRoute,
Expand All @@ -21,8 +21,8 @@ import useBaseRouter from './useBaseRouter';
export default function createLocalizedPathnamesNavigation<
AppLocales extends Locales,
AppPathnames extends Pathnames<AppLocales>
>(input: LocalizedNavigationRoutingConfigInput<AppLocales, AppPathnames>) {
const config = receiveLocalizedNavigationRoutingConfig(input);
>(routing: RoutingConfigLocalizedNavigation<AppLocales, AppPathnames>) {
const config = receiveRoutingConfig(routing);

function useTypedLocale(): AppLocales[number] {
const locale = useLocale();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import React, {ComponentProps, ReactElement, forwardRef} from 'react';
import {
receiveLocalePrefixConfig,
RoutingConfigSharedNavigation
} from '../../routing/config';
import {Locales} from '../../routing/types';
import {ParametersExceptFirst} from '../../shared/types';
import {
SharedNavigationRoutingConfigInput,
receiveSharedNavigationRoutingConfig
} from '../shared/config';
import ClientLink from './ClientLink';
import {clientRedirect, clientPermanentRedirect} from './redirects';
import useBasePathname from './useBasePathname';
import useBaseRouter from './useBaseRouter';

export default function createSharedPathnamesNavigation<
const AppLocales extends Locales
>(input?: SharedNavigationRoutingConfigInput<AppLocales>) {
const config = receiveSharedNavigationRoutingConfig(input);
>(routing?: RoutingConfigSharedNavigation<AppLocales, never>) {
const localePrefix = receiveLocalePrefixConfig(routing?.localePrefix);

type LinkProps = Omit<
ComponentProps<typeof ClientLink<AppLocales>>,
Expand All @@ -23,7 +23,7 @@ export default function createSharedPathnamesNavigation<
return (
<ClientLink<AppLocales>
ref={ref}
localePrefix={config.localePrefix}
localePrefix={localePrefix}
{...props}
/>
);
Expand All @@ -37,30 +37,24 @@ export default function createSharedPathnamesNavigation<
pathname: string,
...args: ParametersExceptFirst<typeof clientRedirect>
) {
return clientRedirect(
{pathname, localePrefix: config.localePrefix},
...args
);
return clientRedirect({pathname, localePrefix}, ...args);
}

function permanentRedirect(
pathname: string,
...args: ParametersExceptFirst<typeof clientPermanentRedirect>
) {
return clientPermanentRedirect(
{pathname, localePrefix: config.localePrefix},
...args
);
return clientPermanentRedirect({pathname, localePrefix}, ...args);
}

function usePathname(): string {
const result = useBasePathname(config.localePrefix);
const result = useBasePathname(localePrefix);
// @ts-expect-error -- Mirror the behavior from Next.js, where `null` is returned when `usePathname` is used outside of Next, but the types indicate that a string is always returned.
return result;
}

function useRouter() {
return useBaseRouter<AppLocales>(config.localePrefix);
return useBaseRouter<AppLocales>(localePrefix);
}

return {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React, {ComponentProps} from 'react';
import {
receiveRoutingConfig,
RoutingConfigLocalizedNavigation
} from '../../routing/config';
import {Locales, Pathnames} from '../../routing/types';
import {getRequestLocale} from '../../server/react-server/RequestLocale';
import {ParametersExceptFirst} from '../../shared/types';
import {
LocalizedNavigationRoutingConfigInput,
receiveLocalizedNavigationRoutingConfig
} from '../shared/config';
import {
HrefOrHrefWithParams,
HrefOrUrlObjectWithParams,
Expand All @@ -18,8 +18,8 @@ import {serverPermanentRedirect, serverRedirect} from './redirects';
export default function createLocalizedPathnamesNavigation<
AppLocales extends Locales,
AppPathnames extends Pathnames<AppLocales>
>(input: LocalizedNavigationRoutingConfigInput<AppLocales, AppPathnames>) {
const config = receiveLocalizedNavigationRoutingConfig(input);
>(routing: RoutingConfigLocalizedNavigation<AppLocales, AppPathnames>) {
const config = receiveRoutingConfig(routing);

type LinkProps<Pathname extends keyof AppPathnames> = Omit<
ComponentProps<typeof ServerLink>,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import React, {ComponentProps} from 'react';
import {
receiveLocalePrefixConfig,
RoutingConfigSharedNavigation
} from '../../routing/config';
import {Locales} from '../../routing/types';
import {ParametersExceptFirst} from '../../shared/types';
import {
SharedNavigationRoutingConfigInput,
receiveSharedNavigationRoutingConfig
} from '../shared/config';
import ServerLink from './ServerLink';
import {serverPermanentRedirect, serverRedirect} from './redirects';

export default function createSharedPathnamesNavigation<
AppLocales extends Locales
>(input?: SharedNavigationRoutingConfigInput<AppLocales>) {
const config = receiveSharedNavigationRoutingConfig(input);
>(routing?: RoutingConfigSharedNavigation<AppLocales, never>) {
const localePrefix = receiveLocalePrefixConfig(routing?.localePrefix);

function notSupported(hookName: string) {
return () => {
Expand All @@ -27,29 +27,21 @@ export default function createSharedPathnamesNavigation<
'localePrefix' | 'locales'
>
) {
return (
<ServerLink<AppLocales> localePrefix={config.localePrefix} {...props} />
);
return <ServerLink<AppLocales> localePrefix={localePrefix} {...props} />;
}

function redirect(
pathname: string,
...args: ParametersExceptFirst<typeof serverRedirect>
) {
return serverRedirect(
{pathname, localePrefix: config.localePrefix},
...args
);
return serverRedirect({pathname, localePrefix}, ...args);
}

function permanentRedirect(
pathname: string,
...args: ParametersExceptFirst<typeof serverPermanentRedirect>
) {
return serverPermanentRedirect(
{pathname, localePrefix: config.localePrefix},
...args
);
return serverPermanentRedirect({pathname, localePrefix}, ...args);
}

return {
Expand Down
64 changes: 0 additions & 64 deletions packages/next-intl/src/navigation/shared/config.tsx

This file was deleted.

41 changes: 29 additions & 12 deletions packages/next-intl/src/routing/config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@ import {
Pathnames
} from './types';

/**
* Maintainer note: The config that is accepted by the middleware, the shared
* and the localized pathnames navigation factory function is slightly
* different. This type declares the shared base config that is accepted by all
* of them. Properties that are different are declared in consuming types.
*/
export type RoutingConfig<
AppLocales extends Locales,
AppPathnames extends Pathnames<AppLocales>
Expand All @@ -34,13 +28,37 @@ export type RoutingConfig<
**/
localePrefix?: LocalePrefix<AppLocales>;

/** Can be used to change the locale handling per domain. */
/**
* Can be used to change the locale handling per domain.
* @see https://next-intl-docs.vercel.app/docs/routing#domains
**/
domains?: DomainsConfig<AppLocales>;

/** A map of localized pathnames per locale. */
/**
* A map of localized pathnames per locale.
* @see https://next-intl-docs.vercel.app/docs/routing#pathnames
**/
pathnames?: AppPathnames;
};

export type RoutingConfigSharedNavigation<
AppLocales extends Locales,
AppPathnames extends Pathnames<AppLocales>
> = Omit<RoutingConfig<AppLocales, AppPathnames>, 'defaultLocale' | 'locales'> &
Partial<
Pick<RoutingConfig<AppLocales, AppPathnames>, 'defaultLocale' | 'locales'>
>;

export type RoutingConfigLocalizedNavigation<
AppLocales extends Locales,
AppPathnames extends Pathnames<AppLocales>
> = Omit<
RoutingConfig<AppLocales, AppPathnames>,
'defaultLocale' | 'pathnames'
> &
Partial<Pick<RoutingConfig<AppLocales, AppPathnames>, 'defaultLocale'>> &
Required<Pick<RoutingConfig<AppLocales, AppPathnames>, 'pathnames'>>;

export type ResolvedRoutingConfig<
AppLocales extends Locales,
AppPathnames extends Pathnames<AppLocales>
Expand All @@ -50,10 +68,9 @@ export type ResolvedRoutingConfig<

export function receiveRoutingConfig<
AppLocales extends Locales,
AppPathnames extends Pathnames<AppLocales>
>(
input: RoutingConfig<AppLocales, AppPathnames>
): ResolvedRoutingConfig<AppLocales, AppPathnames> {
AppPathnames extends Pathnames<AppLocales>,
Config extends Partial<RoutingConfig<AppLocales, AppPathnames>>
>(input: Config) {
return {
...input,
localePrefix: receiveLocalePrefixConfig(input.localePrefix)
Expand Down

0 comments on commit 762465b

Please sign in to comment.