Merge branch 'main' of https://github.com/zen-browser/www
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(prefers-color-scheme: dark)" srcset="https://www.zen-browser.app/logos/zen-alpha-white.svg">
|
<source media="(prefers-color-scheme: dark)" srcset="https://www.zen-browser.app/logos/zen-alpha-white.svg">
|
||||||
<img src="https://www.zen-browser.app/logos/zen-alpha-black.svg" width="64px">
|
<img src="https://cdn.jsdelivr.net/gh/zen-browser/www/public/favicon.ico" width="64px">
|
||||||
</picture>
|
</picture>
|
||||||
</p>
|
</p>
|
||||||
<h1 align="center">
|
<h1 align="center">
|
||||||
|
|||||||
18
messages/README-LANGUAGES.md
Normal file
18
messages/README-LANGUAGES.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Contributing Translations
|
||||||
|
|
||||||
|
To contribute to the translation of your language you must modify the json in `/messages` that is named corresponding to the ISO Language Code of your given language.
|
||||||
|
|
||||||
|
If you do not see a JSON for your language then add the language.
|
||||||
|
|
||||||
|
## Adding a language
|
||||||
|
|
||||||
|
1. To add a language you must add the language to the `const SUPPORTED_LANGUAGES = ['en', 'de'];` variable in the `./src/i18n.ts` file.
|
||||||
|
2. You must create a new `.json` file in the `./messages` directory
|
||||||
|
3. Copy the contents of the `en.json` file, make your way down the key-value pairs and change **only the values** to the translated equivalent.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
7
messages/de.json
Normal file
7
messages/de.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"navigation": {
|
||||||
|
"getting-started": "Erste Schritte",
|
||||||
|
"donate": "Spenden",
|
||||||
|
"useful-links": "Nützliche Links"
|
||||||
|
}
|
||||||
|
}
|
||||||
7
messages/en.json
Normal file
7
messages/en.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"navigation": {
|
||||||
|
"getting-started": "Getting Started",
|
||||||
|
"donate": "Donate",
|
||||||
|
"useful-links": "Useful Links"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
|
const createNextIntlPlugin = require('next-intl/plugin');
|
||||||
const { PHASE_DEVELOPMENT_SERVER } = require('next/constants')
|
const { PHASE_DEVELOPMENT_SERVER } = require('next/constants')
|
||||||
|
|
||||||
|
const withNextIntl = createNextIntlPlugin();
|
||||||
|
|
||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
module.exports = (phase, { defaultConfig }) => {
|
const nextConfig = (phase, { defaultConfig }) => {
|
||||||
const defaultConfigWWW = {
|
const defaultConfigWWW = {
|
||||||
images: {
|
images: {
|
||||||
remotePatterns: [
|
remotePatterns: [
|
||||||
@@ -38,4 +41,5 @@ module.exports = (phase, { defaultConfig }) => {
|
|||||||
output: 'export',
|
output: 'export',
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module.exports = withNextIntl(nextConfig);
|
||||||
|
|||||||
97
package-lock.json
generated
97
package-lock.json
generated
@@ -32,6 +32,7 @@
|
|||||||
"framer-motion": "^11.3.24",
|
"framer-motion": "^11.3.24",
|
||||||
"lucide-react": "^0.400.0",
|
"lucide-react": "^0.400.0",
|
||||||
"next": "14.2.4",
|
"next": "14.2.4",
|
||||||
|
"next-intl": "^3.18.1",
|
||||||
"next-themes": "^0.3.0",
|
"next-themes": "^0.3.0",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
@@ -2456,6 +2457,55 @@
|
|||||||
"integrity": "sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==",
|
"integrity": "sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@formatjs/ecma402-abstract": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-rRqXOqdFmk7RYvj4khklyqzcfQl9vEL/usogncBHRZfZBDOwMGuSRNFl02fu5KGHXdbinju+YXyuR+Nk8xlr/g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@formatjs/intl-localematcher": "0.5.4",
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@formatjs/fast-memoize": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-hnk/nY8FyrL5YxwP9e4r9dqeM6cAbo8PeU9UjyXojZMNvVad2Z06FAVHyR3Ecw6fza+0GH7vdJgiKIVXTMbSBA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@formatjs/icu-messageformat-parser": {
|
||||||
|
"version": "2.7.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.8.tgz",
|
||||||
|
"integrity": "sha512-nBZJYmhpcSX0WeJ5SDYUkZ42AgR3xiyhNCsQweFx3cz/ULJjym8bHAzWKvG5e2+1XO98dBYC0fWeeAECAVSwLA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@formatjs/ecma402-abstract": "2.0.0",
|
||||||
|
"@formatjs/icu-skeleton-parser": "1.8.2",
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@formatjs/icu-skeleton-parser": {
|
||||||
|
"version": "1.8.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.2.tgz",
|
||||||
|
"integrity": "sha512-k4ERKgw7aKGWJZgTarIcNEmvyTVD9FYh0mTrrBMHZ1b8hUu6iOJ4SzsZlo3UNAvHYa+PnvntIwRPt1/vy4nA9Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@formatjs/ecma402-abstract": "2.0.0",
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@formatjs/intl-localematcher": {
|
||||||
|
"version": "0.5.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.4.tgz",
|
||||||
|
"integrity": "sha512-zTwEpWOzZ2CiKcB93BLngUX59hQkuZjT2+SAQEscSm52peDW/getsawMcWF1rGRpMCX6D7nSJA3CzJ8gn13N/g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@hapi/hoek": {
|
"node_modules/@hapi/hoek": {
|
||||||
"version": "9.3.0",
|
"version": "9.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
|
||||||
@@ -8666,6 +8716,18 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/intl-messageformat": {
|
||||||
|
"version": "10.5.14",
|
||||||
|
"resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.5.14.tgz",
|
||||||
|
"integrity": "sha512-IjC6sI0X7YRjjyVH9aUgdftcmZK7WXdHeil4KwbjDnRWjnVitKpAx3rr6t6di1joFp5188VqKcobOPA6mCLG/w==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"dependencies": {
|
||||||
|
"@formatjs/ecma402-abstract": "2.0.0",
|
||||||
|
"@formatjs/fast-memoize": "2.2.0",
|
||||||
|
"@formatjs/icu-messageformat-parser": "2.7.8",
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/invariant": {
|
"node_modules/invariant": {
|
||||||
"version": "2.2.4",
|
"version": "2.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||||
@@ -11390,7 +11452,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
||||||
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
|
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
@@ -11452,6 +11513,27 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/next-intl": {
|
||||||
|
"version": "3.18.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/next-intl/-/next-intl-3.18.1.tgz",
|
||||||
|
"integrity": "sha512-ht8HyroJeiJIte9yhg1f0Nc2rlZmkvSYQ3nhqFVJLzhq7T1Xb8nfjilffrOJc3sA8kEjBOS4bdIrg4YX8REO0Q==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://github.com/sponsors/amannn"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@formatjs/intl-localematcher": "^0.5.4",
|
||||||
|
"negotiator": "^0.6.3",
|
||||||
|
"use-intl": "^3.18.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"next": "^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0",
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/next-themes": {
|
"node_modules/next-themes": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.3.0.tgz",
|
||||||
@@ -15130,6 +15212,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/use-intl": {
|
||||||
|
"version": "3.18.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/use-intl/-/use-intl-3.18.1.tgz",
|
||||||
|
"integrity": "sha512-BFNhVnszG1AB04DbNvJ+TLLd1oBDGergAKI8t9xaE4vDJYZaVKQH4zmpdArbegzTu5U9XMen6w14d1P1hBwKOQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@formatjs/fast-memoize": "^2.2.0",
|
||||||
|
"intl-messageformat": "^10.5.14"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/use-sidecar": {
|
"node_modules/use-sidecar": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz",
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
"framer-motion": "^11.3.24",
|
"framer-motion": "^11.3.24",
|
||||||
"lucide-react": "^0.400.0",
|
"lucide-react": "^0.400.0",
|
||||||
"next": "14.2.4",
|
"next": "14.2.4",
|
||||||
|
"next-intl": "^3.18.1",
|
||||||
"next-themes": "^0.3.0",
|
"next-themes": "^0.3.0",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import { Inter } from "next/font/google";
|
|||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
import { ThemeProvider } from "@/components/theme-provider";
|
import { ThemeProvider } from "@/components/theme-provider";
|
||||||
import StyledComponentsRegistry from "@/lib/styled-components-registry";
|
import StyledComponentsRegistry from "@/lib/styled-components-registry";
|
||||||
|
import {NextIntlClientProvider} from 'next-intl';
|
||||||
|
import {getLocale, getMessages} from 'next-intl/server';
|
||||||
|
|
||||||
const inter = Inter({ subsets: ["latin"] });
|
const inter = Inter({ subsets: ["latin"] });
|
||||||
|
|
||||||
@@ -12,26 +14,32 @@ export const metadata: Metadata = {
|
|||||||
keywords: ["Zen", "Browser", "Zen Browser", "Web", "Internet", "Fast"],
|
keywords: ["Zen", "Browser", "Zen Browser", "Web", "Internet", "Fast"],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function RootLayout({
|
export default async function RootLayout({
|
||||||
children,
|
children,
|
||||||
}: Readonly<{
|
}: Readonly<{
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}>) {
|
}>) {
|
||||||
|
const locale = await getLocale();
|
||||||
|
|
||||||
|
const messages = await getMessages();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang="en" suppressHydrationWarning>
|
<html lang={locale} suppressHydrationWarning>
|
||||||
<head>
|
<head>
|
||||||
<link rel="me" href="https://fosstodon.org/@zenbrowser"></link>
|
<link rel="me" href="https://fosstodon.org/@zenbrowser"></link>
|
||||||
<link rel="alternate" type="application/rss+xml" title="Zen Browser Release Notes" href="https://www.zen-browser.app/feed.xml" />
|
<link rel="alternate" type="application/rss+xml" title="Zen Browser Release Notes" href="https://www.zen-browser.app/feed.xml" />
|
||||||
</head>
|
</head>
|
||||||
<body className={inter.className}>
|
<body className={inter.className}>
|
||||||
<ThemeProvider
|
<NextIntlClientProvider messages={messages}>
|
||||||
attribute="class"
|
<ThemeProvider
|
||||||
defaultTheme="dark"
|
attribute="class"
|
||||||
enableSystem
|
defaultTheme="dark"
|
||||||
disableTransitionOnChange
|
enableSystem
|
||||||
>
|
disableTransitionOnChange
|
||||||
<StyledComponentsRegistry>{children}</StyledComponentsRegistry>
|
>
|
||||||
</ThemeProvider>
|
<StyledComponentsRegistry>{children}</StyledComponentsRegistry>
|
||||||
|
</ThemeProvider>
|
||||||
|
</NextIntlClientProvider>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from './
|
|||||||
|
|
||||||
function Checkmark() {
|
function Checkmark() {
|
||||||
return (
|
return (
|
||||||
<CheckIcon className="text-black rounded-full bg-green-500 dark:bg-green-400 p-1 w-7 h-7" />
|
<CheckIcon className="text-black rounded-full bg-green-500 dark:bg-green-400 p-1 w-7 h-7 flex-none" />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ export default function Features() {
|
|||||||
return (
|
return (
|
||||||
<section className="flex-col w-full" id="features">
|
<section className="flex-col w-full" id="features">
|
||||||
<div className='w-full md:w-5/6 lg:w-3/4 flex flex-col lg:flex-row md:rounded-md mx-auto bg-surface mt-16 shadow'>
|
<div className='w-full md:w-5/6 lg:w-3/4 flex flex-col lg:flex-row md:rounded-md mx-auto bg-surface mt-16 shadow'>
|
||||||
<div className="md:w-1/2 p-5 lg:p-12">
|
<div className="p-5 lg:p-12 flex-1">
|
||||||
<div className="flex p-12 flex-col justify-center">
|
<div className="flex p-12 flex-col justify-center">
|
||||||
<h3 className='text-4xl font-medium text-gray-800 dark:text-gray-100'>Your Browser, your way <PaintBucket className='inline w-10 h-10'></PaintBucket></h3>
|
<h3 className='text-4xl font-medium text-gray-800 dark:text-gray-100'>Your Browser, your way <PaintBucket className='inline w-10 h-10'></PaintBucket></h3>
|
||||||
<p className='text-lg mt-4 text-gray-600 dark:text-gray-300'>With Zen's Theme Store, you can customize your browsing experience to reflect your unique style and preferences. Choose from a wide array of themes, colors, and layouts to make Zen truly your own, transforming your browser into a personalized digital space.</p>
|
<p className='text-lg mt-4 text-gray-600 dark:text-gray-300'>With Zen's Theme Store, you can customize your browsing experience to reflect your unique style and preferences. Choose from a wide array of themes, colors, and layouts to make Zen truly your own, transforming your browser into a personalized digital space.</p>
|
||||||
@@ -86,7 +86,7 @@ export default function Features() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="border-t lg:border-t-0 lg:border-l h-[1px] lg:h-[unset] lg:w-[1px] mx-2"></div>
|
<div className="border-t lg:border-t-0 lg:border-l h-[1px] lg:h-[unset] lg:w-[1px] mx-2"></div>
|
||||||
<div className="md:w-1/2 p-5 lg:p-12">
|
<div className="p-5 lg:p-12 flex-1">
|
||||||
<div className="flex p-12 flex-col justify-center">
|
<div className="flex p-12 flex-col justify-center">
|
||||||
<h3 className='text-4xl font-medium text-gray-800 dark:text-gray-100'>Community driven and Open Source <Link1Icon className='inline w-10 h-10'></Link1Icon></h3>
|
<h3 className='text-4xl font-medium text-gray-800 dark:text-gray-100'>Community driven and Open Source <Link1Icon className='inline w-10 h-10'></Link1Icon></h3>
|
||||||
<p className='text-lg mt-4 text-gray-600 dark:text-gray-300'>Zen thrives on the contributions of its vibrant community. As an open-source project, Zen encourages collaboration and innovation, allowing users and developers alike to shape the future of the browser.</p>
|
<p className='text-lg mt-4 text-gray-600 dark:text-gray-300'>Zen thrives on the contributions of its vibrant community. As an open-source project, Zen encourages collaboration and innovation, allowing users and developers alike to shape the future of the browser.</p>
|
||||||
@@ -104,11 +104,11 @@ export default function Features() {
|
|||||||
</div>
|
</div>
|
||||||
<div className='flex items-center mt-5'>
|
<div className='flex items-center mt-5'>
|
||||||
<Checkmark />
|
<Checkmark />
|
||||||
<p className='ml-2 text-gray-600 dark:text-gray-300'>Automated Releases, to prove security</p>
|
<p className='ml-2 text-gray-600 dark:text-gray-300'>Automated Releases to ensure security</p>
|
||||||
</div>
|
</div>
|
||||||
<div className='flex items-center mt-5'>
|
<div className='flex items-center mt-5'>
|
||||||
<Checkmark />
|
<Checkmark />
|
||||||
<p className='ml-2 text-gray-600 dark:text-gray-300'>Comunity driven</p>
|
<p className='ml-2 text-gray-600 dark:text-gray-300'>Community driven</p>
|
||||||
</div>
|
</div>
|
||||||
<div className='flex items-center mt-5'>
|
<div className='flex items-center mt-5'>
|
||||||
<Checkmark />
|
<Checkmark />
|
||||||
@@ -139,7 +139,7 @@ export default function Features() {
|
|||||||
</div>
|
</div>
|
||||||
<img src="https://cdn.jsdelivr.net/gh/zen-browser/www/public/browser-1.png" alt="Zen Browser" className="rounded-md lg:w-1/2" />
|
<img src="https://cdn.jsdelivr.net/gh/zen-browser/www/public/browser-1.png" alt="Zen Browser" className="rounded-md lg:w-1/2" />
|
||||||
</div>
|
</div>
|
||||||
<div className='w-full md:w-5/6 lg:w-3/4 flex flex-col lg:flex-row md:rounded-md lg:mx-auto bg-surface mt-36 shadow'>
|
<div className='w-full md:w-5/6 lg:w-3/4 flex flex-col lg:flex-row md:rounded-md mx-auto bg-surface mt-36 shadow'>
|
||||||
<img src="https://cdn.jsdelivr.net/gh/zen-browser/www/public/browser-2.png" alt="Zen Browser" className="rounded-md lg:w-1/2" />
|
<img src="https://cdn.jsdelivr.net/gh/zen-browser/www/public/browser-2.png" alt="Zen Browser" className="rounded-md lg:w-1/2" />
|
||||||
<div className='p-16 lg:w-1/2 flex flex-col justify-center'>
|
<div className='p-16 lg:w-1/2 flex flex-col justify-center'>
|
||||||
<h1 className='text-4xl font-medium text-gray-800 dark:text-gray-100'>Split Views</h1>
|
<h1 className='text-4xl font-medium text-gray-800 dark:text-gray-100'>Split Views</h1>
|
||||||
@@ -168,18 +168,18 @@ export default function Features() {
|
|||||||
</div>
|
</div>
|
||||||
<div className='flex items-center mt-4'>
|
<div className='flex items-center mt-4'>
|
||||||
<Question />
|
<Question />
|
||||||
<p className='ml-2 text-gray-600 dark:text-gray-300'>Tab Groups (Comming Soon)</p>
|
<p className='ml-2 text-gray-600 dark:text-gray-300'>Tab Groups (Coming Soon)</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="border-t lg:border-t-0 lg:border-l h-[1px] lg:h-[unset] lg:w-[1px] mx-2"></div>
|
<div className="border-t lg:border-t-0 lg:border-l h-[1px] lg:h-[unset] lg:w-[1px] mx-2"></div>
|
||||||
<div className="flex p-16 lg:w-1/2 flex-col">
|
<div className="flex p-16 lg:w-1/2 flex-col">
|
||||||
<h3 className='text-4xl font-medium text-gray-800 dark:text-gray-100'>Security And Privacy is <span className='text-purple-500 font-bold'>important</span> to us</h3>
|
<h3 className='text-4xl font-medium text-gray-800 dark:text-gray-100'>Security and Privacy is <span className='text-purple-500 font-bold'>important</span> to us</h3>
|
||||||
<p className='text-lg mt-4 text-gray-600 dark:text-gray-300'>
|
<p className='text-lg mt-4 text-gray-600 dark:text-gray-300'>
|
||||||
Zen is based on Firefox, ensuring that your browsing experience prioritizes security and privacy. With advanced tracking protection and minimal data collection, Zen keeps your online activity safe and secure, giving you peace of mind as you explore the web.
|
Zen is based on Firefox, ensuring that your browsing experience prioritizes security and privacy. With advanced tracking protection and minimal data collection, Zen keeps your online activity safe and secure, giving you peace of mind as you explore the web.
|
||||||
</p>
|
</p>
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<Button className='mt-8' variant="ghost" onClick={() => window.open('/download', '_blank')}>Security in zen <ExternalLinkIcon className='opacity-50 h-4 w-4 ml-4' /></Button>
|
<Button className='mt-8' variant="ghost" onClick={() => window.open('/download', '_blank')}>Security in Zen <ExternalLinkIcon className='opacity-50 h-4 w-4 ml-4' /></Button>
|
||||||
<Button className='mt-8' variant="ghost" onClick={() => window.open('/privacy-policy', '_blank')}>Your Privacy <ExternalLinkIcon className='opacity-50 h-4 w-4 ml-4' /></Button>
|
<Button className='mt-8' variant="ghost" onClick={() => window.open('/privacy-policy', '_blank')}>Your Privacy <ExternalLinkIcon className='opacity-50 h-4 w-4 ml-4' /></Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import { ModeToggle } from "./mode-toggle"
|
|||||||
import { MobileNav } from "./mobile-nav"
|
import { MobileNav } from "./mobile-nav"
|
||||||
import { HeartIcon } from "lucide-react"
|
import { HeartIcon } from "lucide-react"
|
||||||
import { HeartFilledIcon } from "@radix-ui/react-icons"
|
import { HeartFilledIcon } from "@radix-ui/react-icons"
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
export const components: { title: string; href: string; description: string }[] = [
|
export const components: { title: string; href: string; description: string }[] = [
|
||||||
{
|
{
|
||||||
@@ -48,6 +49,9 @@ export const components: { title: string; href: string; description: string }[]
|
|||||||
]
|
]
|
||||||
|
|
||||||
export function Navigation() {
|
export function Navigation() {
|
||||||
|
|
||||||
|
const t = useTranslations('navigation');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-background z-40 top-0 left-0 w-full flex fixed border-b border-grey p-2 items-center justify-center">
|
<div className="bg-background z-40 top-0 left-0 w-full flex fixed border-b border-grey p-2 items-center justify-center">
|
||||||
<MobileNav />
|
<MobileNav />
|
||||||
@@ -59,7 +63,7 @@ export function Navigation() {
|
|||||||
</NavigationMenuLink>
|
</NavigationMenuLink>
|
||||||
</NavigationMenuItem>
|
</NavigationMenuItem>
|
||||||
<NavigationMenuItem>
|
<NavigationMenuItem>
|
||||||
<NavigationMenuTrigger>Getting started</NavigationMenuTrigger>
|
<NavigationMenuTrigger>{t('getting-started')}</NavigationMenuTrigger>
|
||||||
<NavigationMenuContent>
|
<NavigationMenuContent>
|
||||||
<ul className="grid gap-3 p-6 md:w-[400px] lg:w-[500px] lg:grid-cols-[.75fr_1fr]">
|
<ul className="grid gap-3 p-6 md:w-[400px] lg:w-[500px] lg:grid-cols-[.75fr_1fr]">
|
||||||
<li className="row-span-3">
|
<li className="row-span-3">
|
||||||
@@ -94,7 +98,7 @@ export function Navigation() {
|
|||||||
<NavigationMenuItem>
|
<NavigationMenuItem>
|
||||||
<NavigationMenuTrigger>
|
<NavigationMenuTrigger>
|
||||||
<HeartFilledIcon className="text-red-500" />
|
<HeartFilledIcon className="text-red-500" />
|
||||||
<span className="ml-2">Donate</span>
|
<span className="ml-2">{t('donate')}</span>
|
||||||
</NavigationMenuTrigger>
|
</NavigationMenuTrigger>
|
||||||
<NavigationMenuContent>
|
<NavigationMenuContent>
|
||||||
<ul className="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px] ">
|
<ul className="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px] ">
|
||||||
@@ -114,7 +118,7 @@ export function Navigation() {
|
|||||||
</NavigationMenuContent>
|
</NavigationMenuContent>
|
||||||
</NavigationMenuItem>
|
</NavigationMenuItem>
|
||||||
<NavigationMenuItem>
|
<NavigationMenuItem>
|
||||||
<NavigationMenuTrigger>Useful Links</NavigationMenuTrigger>
|
<NavigationMenuTrigger>{t('useful-links')}</NavigationMenuTrigger>
|
||||||
<NavigationMenuContent>
|
<NavigationMenuContent>
|
||||||
<ul className="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px] ">
|
<ul className="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px] ">
|
||||||
{components.map((component) => (
|
{components.map((component) => (
|
||||||
|
|||||||
35
src/i18n.ts
Normal file
35
src/i18n.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import { getRequestConfig } from "next-intl/server";
|
||||||
|
import { headers } from "next/headers";
|
||||||
|
|
||||||
|
const SUPPORTED_LANGUAGES = ['en', 'de'];
|
||||||
|
|
||||||
|
export default getRequestConfig(async () => {
|
||||||
|
const headersList = headers();
|
||||||
|
|
||||||
|
const acceptLanguage = headersList.get("accept-language") || "en";
|
||||||
|
|
||||||
|
const [primaryLanguage] = acceptLanguage
|
||||||
|
.split(",")
|
||||||
|
.map((lang) => lang.split(";")[0])
|
||||||
|
.map((lang) => lang.toLowerCase());
|
||||||
|
|
||||||
|
const locale = SUPPORTED_LANGUAGES.includes(primaryLanguage) ? primaryLanguage : 'en';
|
||||||
|
|
||||||
|
try {
|
||||||
|
const messages = (await import(`../messages/${locale}.json`)).default;
|
||||||
|
|
||||||
|
return {
|
||||||
|
locale,
|
||||||
|
messages,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to load messages for locale: ${locale}`, error);
|
||||||
|
|
||||||
|
const fallbackMessages = (await import(`../messages/en.json`)).default;
|
||||||
|
|
||||||
|
return {
|
||||||
|
locale: "en",
|
||||||
|
messages: fallbackMessages,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user