diff --git a/package.json b/package.json
index 078b9cb..1554abc 100644
--- a/package.json
+++ b/package.json
@@ -10,8 +10,10 @@
"preview": "vite preview"
},
"dependencies": {
+ "i18next": "^23.4.6",
"react": "^18.2.0",
"react-dom": "^18.2.0",
+ "react-i18next": "^13.2.1",
"styled-components": "^6.0.7"
},
"devDependencies": {
diff --git a/src/App.tsx b/src/App.tsx
index 44c7607..65f71ae 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -3,6 +3,7 @@ import { theme } from './theme';
import { GlobalStyles } from './components/styles/Global.styled';
import Navbar from './components/Navbar';
import LandingSection from './components/LandingSection';
+import './i18n';
function App() {
return (
diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx
index 5f956c2..2e75763 100644
--- a/src/components/Navbar.tsx
+++ b/src/components/Navbar.tsx
@@ -1,4 +1,11 @@
-import { StyledNavbar, StyledNavlink, StyledNavlinkBrand, StyledNavlinkList } from './styles/Navbar.styled';
+import { useTranslation } from 'react-i18next';
+import {
+ StyledLangButton,
+ StyledNavbar,
+ StyledNavlink,
+ StyledNavlinkBrand,
+ StyledNavlinkList,
+} from './styles/Navbar.styled';
interface NavLink {
title: string;
@@ -6,46 +13,62 @@ interface NavLink {
}
function NavlinkList(props: { navlinks: NavLink[] }) {
+ const { t } = useTranslation();
+
return (
<>
{props.navlinks.map((navlink) => (
- {navlink.title}
+ {t(`navbar.${navlink.title}`)}
))}
+
+
>
);
}
-function NavlinkBrand(props: { name: string }) {
- return {props.name};
+function LanguageChoice() {
+ const { i18n } = useTranslation();
+
+ function changeLanguage() {
+ i18n.changeLanguage(i18n.language == 'pl' ? 'en' : 'pl');
+ }
+
+ return (
+ <>
+ {i18n.language}
+ >
+ );
}
const navlinks = [
+ // {
+ // title: 'home',
+ // href: '#',
+ // },
{
- title: 'HOME',
+ title: 'about',
href: '#',
},
{
- title: 'ABOUT',
+ title: 'projects',
href: '#',
},
{
- title: 'PROJECTS',
- href: '#',
- },
- {
- title: 'CONTACT',
+ title: 'contact',
href: '#',
},
];
export default function Navbar() {
+ const { t } = useTranslation();
+
return (
-
+ {t('navbar.title')}
);
diff --git a/src/components/styles/Global.styled.ts b/src/components/styles/Global.styled.ts
index ef22ebe..961ffbc 100644
--- a/src/components/styles/Global.styled.ts
+++ b/src/components/styles/Global.styled.ts
@@ -46,6 +46,10 @@ export const GlobalStyles = createGlobalStyle`
}
}
+ button {
+ border: none;
+ }
+
@keyframes typing {
to { left: 100% }
}
diff --git a/src/components/styles/Navbar.styled.ts b/src/components/styles/Navbar.styled.ts
index 1fa04cb..20621dc 100644
--- a/src/components/styles/Navbar.styled.ts
+++ b/src/components/styles/Navbar.styled.ts
@@ -19,6 +19,7 @@ export const StyledNavlinkBrand = styled.div`
export const StyledNavlinkList = styled.div`
display: flex;
+ align-items: center;
gap: 1em;
font-size: 1.1em;
`;
@@ -27,3 +28,15 @@ export const StyledNavlink = styled.a`
/* color: black; */
font-weight: bold;
`;
+
+export const StyledLangButton = styled.button`
+ font-size: 1em;
+ font-weight: bold;
+
+ padding: 0.25em 1em;
+ text-transform: uppercase;
+ cursor: pointer;
+
+ border: 1px solid ${({ theme }) => theme.colors.primary};
+ background: none;
+`;
diff --git a/src/i18n.ts b/src/i18n.ts
new file mode 100644
index 0000000..6231fac
--- /dev/null
+++ b/src/i18n.ts
@@ -0,0 +1,25 @@
+import i18n from 'i18next';
+import { initReactI18next } from 'react-i18next';
+
+import localePL from './locales/pl.json';
+import localeEN from './locales/en.json';
+
+const resources = {
+ en: {
+ translation: localeEN,
+ },
+ pl: {
+ translation: localePL,
+ },
+};
+
+i18n.use(initReactI18next).init({
+ resources,
+ lng: 'pl',
+
+ interpolation: {
+ escapeValue: false,
+ },
+});
+
+export default i18n;
diff --git a/src/locales/en.json b/src/locales/en.json
new file mode 100644
index 0000000..0072346
--- /dev/null
+++ b/src/locales/en.json
@@ -0,0 +1,9 @@
+{
+ "navbar": {
+ "title": "Spythere Portfolio",
+ "home": "HOME",
+ "about": "ABOUT",
+ "projects": "PROJECTS",
+ "contact": "CONTACT"
+ }
+}
diff --git a/src/locales/pl.json b/src/locales/pl.json
new file mode 100644
index 0000000..a87e9c0
--- /dev/null
+++ b/src/locales/pl.json
@@ -0,0 +1,9 @@
+{
+ "navbar": {
+ "title": "Spythere Portfolio",
+ "home": "",
+ "about": "O MNIE",
+ "projects": "PROJEKTY",
+ "contact": "KONTAKT"
+ }
+}
diff --git a/yarn.lock b/yarn.lock
index 015af8e..ba42bfe 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1034,7 +1034,7 @@
resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310"
integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==
-"@babel/runtime@^7.8.4":
+"@babel/runtime@^7.22.5", "@babel/runtime@^7.8.4":
version "7.22.11"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.11.tgz#7a9ba3bbe406ad6f9e8dd4da2ece453eb23a77a4"
integrity sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==
@@ -2023,6 +2023,20 @@ has@^1.0.3:
dependencies:
function-bind "^1.1.1"
+html-parse-stringify@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz#dfc1017347ce9f77c8141a507f233040c59c55d2"
+ integrity sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==
+ dependencies:
+ void-elements "3.1.0"
+
+i18next@^23.4.6:
+ version "23.4.6"
+ resolved "https://registry.yarnpkg.com/i18next/-/i18next-23.4.6.tgz#10211e72d5bd29e274baae99c6cc0178b93a93f8"
+ integrity sha512-jBE8bui969Ygv7TVYp0pwDZB7+he0qsU+nz7EcfdqSh+QvKjEfl9YPRQd/KrGiMhTYFGkeuPaeITenKK/bSFDg==
+ dependencies:
+ "@babel/runtime" "^7.22.5"
+
ignore@^5.2.0, ignore@^5.2.4:
version "5.2.4"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324"
@@ -2365,6 +2379,14 @@ react-dom@^18.2.0:
loose-envify "^1.1.0"
scheduler "^0.23.0"
+react-i18next@^13.2.1:
+ version "13.2.1"
+ resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-13.2.1.tgz#57cf7c07778281bdb1e0a1fd60ca5fcc35c0a786"
+ integrity sha512-XhMsnGgJnytWfi2Q70HMYfm+zysPUu1Pz+It6I87WwaeclGY+W8W1c11uENEMNg+Xb+mNrGuo8GEDuQDOgO+oQ==
+ dependencies:
+ "@babel/runtime" "^7.22.5"
+ html-parse-stringify "^3.0.1"
+
react-refresh@^0.14.0:
version "0.14.0"
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e"
@@ -2686,6 +2708,11 @@ vite@^4.4.5:
optionalDependencies:
fsevents "~2.3.2"
+void-elements@3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09"
+ integrity sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==
+
which@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"