next-translate
next-translate copied to clipboard
Add optional param t to Trans component
Iām making a page and it has a view that uses aprox 25 json files. But I need to load only one file by default, and the other files will be needed based on how the user interact with it. I used DynamicNamespace but this component load all files by default, this is not necesary because it may use only use 6 of 25 json files. I saw the source code and I think this problem it's easy to solve if an optional parameter can be added to the Trans component.
@piiok DynamicNamespace
loads the files that you specify... Did you try something like this?
import React, { useState } from 'react'
import Trans from 'next-translate/Trans'
import DynamicNamespaces from 'next-translate/DynamicNamespaces'
const [INITIAL, SECOND, THIRD, FINAL] = [0, 1, 2, 3]
const namespaces = ['initial', 'second', 'third', 'final']
export default function ExampleWithDynamicNamespace() {
const [status, setStatus] = useState(INITIAL)
const [ns, setNs] = useState(namespaces.slice(0, 1))
function nextStatus() {
const newStatus = status + 1
setStatus(newStatus)
setNs(oldNs => [...oldNs, namespaces[newStatus]])
}
return (
<DynamicNamespaces
// Force to download on each status change
key={`ns-${status}`}
// Using dynamic import only downloads the chunks that have not
// yet been downloaded, those that have already been downloaded.
// are not downloaded again.
namespaces={ns}
fallback="Loading..."
>
{(() => {
if (status === INITIAL) return <Trans i18nKey="initial:title" />
if (status === SECOND) return <Trans i18nKey="second:title" />
if (status === THIRD) return <Trans i18nKey="third:title" />
if (status === FINAL) return <Trans i18nKey="final:title" />
})()}
{status !== FINAL && <button onClick={nextStatus}>Next status</button>}
</DynamicNamespaces>
)
}
The json is split because there are so much content. So i have 25 namespaces for each case. But i need load json file only if user need this namespace and DynamicNamespace load all.
I'm trying to do my own DynamicNamespace
import React, { useContext, useEffect, useState } from 'react';
import useSWR from 'swr';
import { swrFetcher } from '@/utils/api';
import { internalApiPaths } from '@/constants';
import PropTypes from 'prop-types';
import I18nProvider, { InternalContext } from 'next-translate/I18nProvider';
import useTranslation from 'next-translate/useTranslation';
const GetterNamespaces = (props) => {
const internal = useContext(InternalContext);
const { namespace: namespaceProp, loadedNamespace, loading: Loading, deleteUnused, children } = props;
const { lang } = useTranslation();
const [needNs, setNeedNs] = useState([]);
const [ns, setNs] = useState({});
const [loaded] = useState(loadedNamespace);
const { data, isValidating } = useSWR(
needNs.length !== 0 ? [internalApiPaths.NAMESPACE_FILE, 'POST', lang, ...needNs] : null,
swrFetcher
);
const loading = !data && isValidating;
useEffect(() => {
if (namespaceProp && namespaceProp !== loaded && !Object.keys(ns).includes(namespaceProp)) {
setNeedNs([namespaceProp]);
}
}, [namespaceProp]);
useEffect(() => {
if (data) {
const newNs = Object.assign(deleteUnused ? {} : ns, data);
setNs(newNs);
}
}, [data]);
return loading ? (
Loading
) : (
<I18nProvider lang={lang} namespaces={ns}>
<InternalContext.Provider value={{ ns, config: internal.config }}>{children}</InternalContext.Provider>
</I18nProvider>
);
};
GetterNamespaces.defaultProps = {
loadedNamespace: '',
deleteUnused: true,
loading: 'loading...',
children: null,
};
GetterNamespaces.propTypes = {
namespace: PropTypes.string.isRequired,
loadedNamespace: PropTypes.string,
deleteUnused: PropTypes.bool,
loading: PropTypes.oneOfType([PropTypes.element, PropTypes.string]),
children: PropTypes.element,
};
export default GetterNamespaces;
@piiok did you finally solve the problem?