import { Link, useInRouterContext, useParams } from '@modern-js/runtime/router';
import type React from 'react';
import { useModernI18n } from './context';
import { buildLocalizedUrl } from './utils';
export interface I18nLinkProps {
to: string;
children: React.ReactNode;
[key: string]: any; // Allow other props to be passed through
}
/**
* I18nLink component that automatically adds language prefix to navigation links.
* This component should be used within a :lang dynamic route context.
*
* @example
* ```tsx
* // When current language is 'en' and to="/about"
* // The actual link will be "/en/about"
* About
*
* // When current language is 'zh' and to="/"
* // The actual link will be "/zh"
* Home
* ```
*/
// Use static imports to avoid breaking router tree-shaking. Detect router context via useInRouterContext.
const useRouterHooks = () => {
const inRouter = useInRouterContext();
return {
Link: inRouter ? Link : null,
params: inRouter ? useParams() : ({} as any),
hasRouter: inRouter,
};
};
export const I18nLink: React.FC = ({
to,
children,
...props
}) => {
const { Link, params, hasRouter } = useRouterHooks();
const { language, supportedLanguages } = useModernI18n();
// Get the current language from context (which reflects the actual current language)
// URL params might be stale after language changes, so we prioritize the context language
const currentLang = language;
// Build the localized URL by adding language prefix
const localizedTo = buildLocalizedUrl(to, currentLang, supportedLanguages);
// In development mode, warn if used outside of :lang route context
if (process.env.NODE_ENV === 'development' && hasRouter && !params.lang) {
console.warn(
'I18nLink is being used outside of a :lang dynamic route context. ' +
'This may cause unexpected behavior. Please ensure I18nLink is used within a route that has a :lang parameter.',
);
}
// If router is not available, render as a regular anchor tag
if (!hasRouter || !Link) {
return (
{children}
);
}
return (
{children}
);
};
export default I18nLink;