├── .env.example
├── .eslintrc.json
├── .gitignore
├── .vscode
├── extensions.json
└── settings.json
├── README.md
├── app
├── [locale]
│ ├── (frontend)
│ │ ├── (home)
│ │ │ └── page.tsx
│ │ ├── [...rest]
│ │ │ └── page.tsx
│ │ └── layout.tsx
│ ├── globals.css
│ ├── layout.tsx
│ └── not-found.tsx
├── api
│ ├── google
│ │ └── serp
│ │ │ └── route.ts
│ ├── layout.tsx
│ ├── location
│ │ └── route.ts
│ └── snapshot
│ │ └── [id]
│ │ └── route.ts
├── favicon.ico
└── robots.ts
├── bin
├── generateComponentsMarkdownData.ts
└── watcher.ts
├── components.json
├── components
├── frontend
│ ├── google
│ │ ├── desktop
│ │ │ ├── DownloadCsv.tsx
│ │ │ ├── FeaturedSnippets.tsx
│ │ │ ├── InlineImages.tsx
│ │ │ ├── InlineVideos.tsx
│ │ │ ├── LocalResults.tsx
│ │ │ ├── PeopleAlsoAsk.tsx
│ │ │ ├── Recipes.tsx
│ │ │ ├── RelatedSearches.tsx
│ │ │ ├── ThinksToKnow.tsx
│ │ │ ├── TopStories.tsx
│ │ │ ├── Twitter.tsx
│ │ │ ├── Video.tsx
│ │ │ └── index.tsx
│ │ └── shared
│ │ │ ├── FilterUrl.tsx
│ │ │ ├── ItemNormal.tsx
│ │ │ ├── ItemSource.tsx
│ │ │ ├── SiteIcon.tsx
│ │ │ └── TypeTitle.tsx
│ ├── page
│ │ └── home
│ │ │ ├── faqs.tsx
│ │ │ ├── form.tsx
│ │ │ ├── landing.tsx
│ │ │ ├── main.tsx
│ │ │ ├── results.tsx
│ │ │ ├── status.tsx
│ │ │ └── title-cell.tsx
│ └── shared
│ │ ├── footer.tsx
│ │ ├── header.tsx
│ │ ├── nav-bar.tsx
│ │ ├── not-found.tsx
│ │ └── top.tsx
├── shared
│ ├── locale-switch.tsx
│ ├── markdown.tsx
│ └── mode-toggle.tsx
└── ui
│ ├── accordion.tsx
│ ├── alert-dialog.tsx
│ ├── avatar.tsx
│ ├── badge.tsx
│ ├── button.tsx
│ ├── card.tsx
│ ├── carousel.tsx
│ ├── combobox.tsx
│ ├── command.tsx
│ ├── dialog.tsx
│ ├── dropdown-menu.tsx
│ ├── form.tsx
│ ├── input.tsx
│ ├── label.tsx
│ ├── popover.tsx
│ ├── select.tsx
│ ├── sheet.tsx
│ ├── skeleton.tsx
│ ├── switch.tsx
│ ├── table.tsx
│ ├── toast.tsx
│ ├── toaster.tsx
│ ├── typography.tsx
│ └── use-toast.ts
├── config.ts
├── content
└── components
│ └── home
│ ├── block1
│ ├── de.md
│ ├── en.md
│ ├── es.md
│ ├── fr.md
│ ├── it.md
│ ├── ja.md
│ ├── ko.md
│ ├── nl.md
│ ├── pl.md
│ ├── pt.md
│ ├── ru.md
│ ├── sv.md
│ ├── tr.md
│ └── zh.md
│ └── block2
│ ├── de.md
│ ├── en.md
│ ├── es.md
│ ├── fr.md
│ ├── it.md
│ ├── ja.md
│ ├── ko.md
│ ├── nl.md
│ ├── pl.md
│ ├── pt.md
│ ├── ru.md
│ ├── sv.md
│ ├── tr.md
│ └── zh.md
├── country.ts
├── data
├── generated
│ └── components-markdown.json
└── geotargets.csv
├── i18n.ts
├── image.png
├── language.ts
├── lib
├── api.ts
├── i18n.ts
└── utils.ts
├── locales
├── de.json
├── en.json
├── es.json
├── fr.json
├── it.json
├── ja.json
├── ko.json
├── nl.json
├── pl.json
├── ru.json
├── sv.json
├── tr.json
└── zh.json
├── middleware.ts
├── models
└── GeoTrgets.ts
├── next.config.mjs
├── package-lock.json
├── package.json
├── postcss.config.mjs
├── public
├── apiKey.png
├── logo.png
├── next.svg
└── vercel.svg
├── schema
└── index.ts
├── tailwind.config.ts
└── tsconfig.json
/.env.example:
--------------------------------------------------------------------------------
1 | # Get Your API Key: https://www.serp.ing
2 | SERPING_US_EAST_1_API_KEY=
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "next/core-web-vitals",
4 | "eslint:recommended",
5 | "plugin:@typescript-eslint/recommended",
6 | "plugin:react/recommended"
7 | ],
8 | "plugins": [
9 | "react",
10 | "@typescript-eslint",
11 | "react-hooks"
12 | ],
13 | "rules": {
14 | "react/react-in-jsx-scope": "off",
15 | "react/prop-types": "off",
16 | "@typescript-eslint/no-explicit-any": "warn",
17 | "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
18 | "react-hooks/exhaustive-deps": "warn",
19 | "prefer-const": "error",
20 | "react/no-unknown-property": ["error", { "ignore": ["cmdk-input-wrapper"] }],
21 | "@next/next/no-img-element": "off",
22 | "jsx-a11y/alt-text": "off"
23 | },
24 | "settings": {
25 | "react": {
26 | "version": "detect"
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "esbenp.prettier-vscode",
4 | "dbaeumer.vscode-eslint",
5 | "lokalise.i18n-ally",
6 | "bradlc.vscode-tailwindcss"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.formatOnSave": true,
3 | "editor.codeActionsOnSave": {
4 | "source.organizeImports": "explicit",
5 | "source.fixAll": "explicit"
6 | },
7 | "tailwindCSS.experimental.classRegex": [
8 | ["cn\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"]
9 | ],
10 | "typescript.preferences.importModuleSpecifier": "shortest",
11 | "typescript.tsdk": "node_modules/typescript/lib",
12 | "eslint.workingDirectories": [{ "mode": "auto" }],
13 | "eslint.debug": true,
14 | "i18n-ally.localesPaths": ["locales"],
15 | "i18n-ally.keystyle": "nested",
16 | "i18n-ally.enabledFrameworks": ["next-intl"]
17 | }
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SERP Checker
2 |
3 | Analyze SERPs from 230+ Countries with SERP Checking
4 |
5 | SERP Checking offers a powerful, free SERP checker designed to give you comprehensive insights into Google's search engine results pages (SERPs) for any keyword. Our tool stands out with unparalleled global coverage and detailed analysis of SERP features and Rich Results.
6 |
7 | ## Get Your SERP API KEY
8 |
9 | To access the SERP API and start making requests, you'll need your API key. Follow these steps to get your key:
10 |
11 | 1. **Visit the SERP API Website:**
12 | Go to the SERP API website at [SERPING](https://www.serp.ing/) to sign up or log in to your account.
13 |
14 | 2. **Obtain Your API Key:**
15 | After logging in, navigate to the [API section](https://www.serp.ing/app/settings/team/tokens) or dashboard to find your unique API key. This key will be required to authenticate your API requests.
16 |
17 |
18 | 
19 |
20 | 3. **Use Your API Key:**
21 | Once you have your API key, you can use it in your requests to the SERP API. Set the key in your environment variable or directly in your code as shown below:
22 |
23 |
24 | ```sh
25 | SERPING_US_EAST_1_API_KEY=your_serping_api_key
26 | ```
27 |
28 | ## Getting Started
29 |
30 | First, run the development server:
31 |
32 | ```bash
33 | npm run dev
34 | # or
35 | yarn dev
36 | # or
37 | pnpm dev
38 | # or
39 | bun dev
40 | ```
41 |
42 | ## Learn More
43 |
44 | To learn more about Next.js, take a look at the following resources:
45 |
46 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
47 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
48 |
49 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
50 |
51 | ## Deploy on Vercel
52 |
53 | You can deploy this project to Vercel with the following button:
54 |
55 | [](https://vercel.com/import/project?template=https://github.com/serping/serp-checker)
56 |
--------------------------------------------------------------------------------
/app/[locale]/(frontend)/(home)/page.tsx:
--------------------------------------------------------------------------------
1 |
2 | import { LocaleType } from "@/config";
3 | import { Main } from "@/frontend/page/home/main";
4 | import { getComponentMarkdown } from "@/i18n";
5 |
6 | export default function Home({
7 | params
8 | }: Readonly<{
9 | params: { locale: string; };
10 | }>) {
11 | // Load by key: data/generated/components-markdown.json
12 | const markdownContents = {
13 | block1: getComponentMarkdown({
14 | locale: params.locale as LocaleType,
15 | componentPathName: "home/block1"
16 | }),
17 | block2: getComponentMarkdown({
18 | locale: params.locale as LocaleType,
19 | componentPathName: "home/block2"
20 | }),
21 | }
22 | return (
23 |
24 |
25 |
26 | );
27 | }
28 |
--------------------------------------------------------------------------------
/app/[locale]/(frontend)/[...rest]/page.tsx:
--------------------------------------------------------------------------------
1 | import { NotFound } from "@/frontend/shared/not-found";
2 |
3 | export default function NotFoundPage() {
4 | return ;
5 | }
6 |
--------------------------------------------------------------------------------
/app/[locale]/(frontend)/layout.tsx:
--------------------------------------------------------------------------------
1 | import { Footer } from "@/frontend/shared/footer";
2 | import { Header } from "@/frontend/shared/header";
3 | import { Top } from "@/frontend/shared/top";
4 | import type { PropsWithChildren } from "react";
5 |
6 | export default function FrontendLayout({ children }: PropsWithChildren) {
7 | return (
8 | <>
9 |
10 |
11 | {children}
12 |
13 |
14 |
15 | >
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/app/[locale]/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | @layer base {
6 | :root {
7 | --background: 0 0% 100%;
8 | --foreground: 222.2 84% 4.9%;
9 | --card: 0 0% 100%;
10 | --card-foreground: 222.2 84% 4.9%;
11 | --popover: 0 0% 100%;
12 | --popover-foreground: 222.2 84% 4.9%;
13 | --primary: 221.2 83.2% 53.3%;
14 | --primary-foreground: 210 40% 98%;
15 | --secondary: 210 40% 96.1%;
16 | --secondary-foreground: 222.2 47.4% 11.2%;
17 | --muted: 210 40% 96.1%;
18 | --muted-foreground: 215.4 16.3% 46.9%;
19 | --accent: 210 40% 96.1%;
20 | --accent-foreground: 222.2 47.4% 11.2%;
21 | --destructive: 0 72.22% 50.59%;
22 | --destructive-foreground: 210 40% 98%;
23 | --border: 214.3 31.8% 91.4%;
24 | --input: 214.3 31.8% 91.4%;
25 | --ring: 221.2 83.2% 53.3%;
26 | --radius: 0.5rem;
27 | }
28 | .dark {
29 | --background: 222.2 84% 4.9%;
30 | --foreground: 210 40% 98%;
31 | --card: 222.2 84% 4.9%;
32 | --card-foreground: 210 40% 98%;
33 | --popover: 222.2 84% 4.9%;
34 | --popover-foreground: 210 40% 98%;
35 | --primary: 217.2 91.2% 59.8%;
36 | --primary-foreground: 222.2 47.4% 11.2%;
37 | --secondary: 217.2 32.6% 17.5%;
38 | --secondary-foreground: 210 40% 98%;
39 | --muted: 217.2 32.6% 17.5%;
40 | --muted-foreground: 215 20.2% 65.1%;
41 | --accent: 217.2 32.6% 17.5%;
42 | --accent-foreground: 210 40% 98%;
43 | --destructive: 0 62.8% 30.6%;
44 | --destructive-foreground: 210 40% 98%;
45 | --border: 217.2 32.6% 17.5%;
46 | --input: 217.2 32.6% 17.5%;
47 | --ring: 224.3 76.3% 48%;
48 | }
49 | }
50 |
51 | @layer base {
52 | * {
53 | @apply border-border;
54 | }
55 | body {
56 | @apply bg-background text-foreground;
57 | }
58 | }
--------------------------------------------------------------------------------
/app/[locale]/layout.tsx:
--------------------------------------------------------------------------------
1 |
2 | import { appConfig, type LocaleType } from "@/config";
3 | import { getMessagesForLocale } from "@/i18n";
4 | import { cn, createAlternates } from "@/lib/utils";
5 | import { GoogleAnalytics } from '@next/third-parties/google';
6 | import type { Metadata } from "next";
7 | import { NextIntlClientProvider } from "next-intl";
8 | import { getTranslations } from "next-intl/server";
9 | import { ThemeProvider } from "next-themes";
10 | import { Inter as FontSans } from "next/font/google";
11 | import { notFound } from "next/navigation";
12 | import NextTopLoader from "nextjs-toploader";
13 |
14 | import { headers } from "next/headers";
15 | import "./globals.css";
16 |
17 | const fontSans = FontSans({
18 | subsets: ["latin"],
19 | variable: "--font-sans",
20 | })
21 |
22 | export async function generateMetadata(locale: LocaleType): Promise {
23 | const t = await getTranslations(locale);
24 | const headersList = headers();
25 |
26 | return {
27 | title: t('frontend.meta.default.title'),
28 | description: t('frontend.meta.default.description'),
29 | alternates: createAlternates({ headers: headersList })
30 | };
31 | }
32 |
33 | export default function RootLayout({
34 | children,
35 | params
36 | }: Readonly<{
37 | children: React.ReactNode;
38 | params: { locale: string };
39 | }>) {
40 |
41 | const { locale } = params as { locale: LocaleType };
42 |
43 | if (!appConfig.i18n.locales.includes(locale)) {
44 | notFound();
45 | }
46 | const messages = getMessagesForLocale(locale);
47 |
48 | return (
49 |
50 |
56 |
57 |
58 |
64 | {children}
65 |
66 |
67 | {appConfig.gaId && }
68 |
69 |
70 | );
71 | }
72 |
--------------------------------------------------------------------------------
/app/[locale]/not-found.tsx:
--------------------------------------------------------------------------------
1 | import { redirect } from 'next/navigation';
2 |
3 | export default function RootPage() {
4 | redirect('/404');
5 | }
--------------------------------------------------------------------------------
/app/api/google/serp/route.ts:
--------------------------------------------------------------------------------
1 |
2 | import { appConfig } from "@/config";
3 | import Serping from "serping";
4 | import { GoogleSerpSearchParamSchema } from 'serping/zod/google/base';
5 | export async function POST(req: Request) {
6 | const data = await req.json();
7 | const { body } = data;
8 | const { serpingApi } = appConfig;
9 | try {
10 | const searchParams = GoogleSerpSearchParamSchema.parse(JSON.parse(body));
11 | const serping = new Serping({ region: "us-east-1", apiKey: serpingApi["us-east-1"].apiKey });
12 | const data = await serping.googleSerp(searchParams);
13 | return new Response(
14 | JSON.stringify(data),
15 | {
16 | status: 200,
17 | headers: { 'Content-Type': 'application/json' }
18 | }
19 | );
20 | } catch (error: unknown) {
21 | console.log("error", error)
22 | const typedError = error as Error;
23 | return new Response(
24 | JSON.stringify({ error: typedError.message }),
25 | {
26 | status: 500,
27 | headers: { 'Content-Type': 'application/json' }
28 | }
29 | );
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/api/layout.tsx:
--------------------------------------------------------------------------------
1 | export const metadata = {
2 | title: 'Next.js',
3 | description: 'Generated by Next.js',
4 | }
5 |
6 | export default function RootLayout({
7 | children,
8 | }: {
9 | children: React.ReactNode
10 | }) {
11 | return (
12 |
13 | {children}
14 |
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/app/api/location/route.ts:
--------------------------------------------------------------------------------
1 | import { GeoTargets, csvData, dataLoaded, type Row } from "@/models/GeoTrgets";
2 |
3 |
4 |
5 | export async function GET(req: Request) {
6 | if (!dataLoaded) GeoTargets();
7 | while (!dataLoaded) {
8 | await new Promise(resolve => setTimeout(resolve, 100));
9 | }
10 | const { searchParams } = new URL(req.url);
11 | const rows: Row[] = [];
12 | const q = searchParams.get('q') || '';
13 | const num = searchParams.get('num') || '10';
14 | const start = searchParams.get('start') || '0';
15 |
16 | try {
17 | if (!q) {
18 | throw new Error('q is empty!');
19 | }
20 |
21 | const startInt = parseInt(start, 10) || 0;
22 | const numInt = parseInt(num, 10) || 10;
23 | let total_count = 0;
24 |
25 | csvData.forEach((row) => {
26 | const canonicalName = row['Canonical Name'];
27 | const matches = canonicalName.match(new RegExp(q, 'i'));
28 |
29 | if (matches) {
30 | total_count += 1;
31 |
32 | if (total_count > startInt && rows.length < numInt) {
33 | rows.push(row);
34 | }
35 | }
36 | });
37 |
38 | return new Response(
39 | JSON.stringify({ data: rows, total_count }),
40 | {
41 | status: 200,
42 | headers: { 'Content-Type': 'application/json' }
43 | }
44 | );
45 |
46 | } catch (error: any) {
47 | return new Response(
48 | JSON.stringify({ error: error.message }),
49 | {
50 | status: 500,
51 | headers: { 'Content-Type': 'application/json' }
52 | }
53 | );
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/app/api/snapshot/[id]/route.ts:
--------------------------------------------------------------------------------
1 |
2 | import { appConfig } from "@/config";
3 | import { redirect } from 'next/navigation';
4 | import Serping from "serping";
5 | export async function GET(__req: Request, { params }: { params: { id: string } }) {
6 | const { serpingApi } = appConfig;
7 | try {
8 | const { id } = params;
9 | const serping = new Serping({ region: "us-east-1", apiKey: serpingApi["us-east-1"].apiKey });
10 | const data = await serping.googleSerpSnapshot({ id });
11 | return new Response(
12 | data,
13 | {
14 | status: 200,
15 | headers: {
16 | 'Content-Type': 'text/html; charset=utf-8;',
17 | 'Cache-Control': 'public, max-age=2592000, stale-while-revalidate=59'
18 | }
19 | }
20 | );
21 | } catch (error: any) {
22 | console.log("error", error)
23 | redirect('/404');
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/serping/serp-checker/27c23062dbdadfdf56210c7a7929f47079b2dfbf/app/favicon.ico
--------------------------------------------------------------------------------
/app/robots.ts:
--------------------------------------------------------------------------------
1 | import type { MetadataRoute } from "next";
2 |
3 | export default function robots(): MetadataRoute.Robots {
4 | return {
5 | rules: {
6 | userAgent: "*",
7 | allow: "/",
8 | }
9 | };
10 | }
11 |
--------------------------------------------------------------------------------
/bin/generateComponentsMarkdownData.ts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env tsx
2 |
3 | import fs from 'fs';
4 | import path from 'path';
5 | import { appConfig, type LocaleType } from '../config';
6 | import { componentsMarkdownFile, contentComponentsMarkdownDir } from '../i18n';
7 |
8 | const { i18n: { locales } } = appConfig;
9 |
10 | const contentDir = path.join(process.cwd(), contentComponentsMarkdownDir);
11 |
12 | function generateComponentMarkdownData(dir: string, jsonData: Record = {}): Record {
13 | const entries = fs.readdirSync(dir, { withFileTypes: true });
14 |
15 | entries.forEach(entry => {
16 | const fullPath = path.join(dir, entry.name);
17 | if (entry.isDirectory()) {
18 | generateComponentMarkdownData(fullPath, jsonData);
19 | } else if (entry.isFile() && entry.name.endsWith('.md')) {
20 | const relativePath = path.relative(contentDir, path.dirname(fullPath)).replace(/\\/g, '/');
21 | const locale = path.basename(entry.name, '.md') as LocaleType;
22 |
23 | if (locales.includes(locale)) {
24 | if (!jsonData[relativePath]) {
25 | jsonData[relativePath] = { locales: [] };
26 | }
27 | if (!jsonData[relativePath].locales.includes(locale)) {
28 | jsonData[relativePath].locales.push(locale);
29 | }
30 | }
31 | }
32 | });
33 |
34 | return jsonData;
35 | }
36 |
37 | function writeComponentMarkdownData(): void {
38 | const jsonData = generateComponentMarkdownData(contentDir);
39 | const outputDir = path.dirname(componentsMarkdownFile);
40 |
41 | if (!fs.existsSync(outputDir)) {
42 | fs.mkdirSync(outputDir, { recursive: true });
43 | }
44 |
45 | fs.writeFileSync(
46 | componentsMarkdownFile,
47 | JSON.stringify(jsonData, null, 2),
48 | 'utf8'
49 | );
50 |
51 | console.log(`Generated components markdown data at ${componentsMarkdownFile}`);
52 | }
53 |
54 | writeComponentMarkdownData();
--------------------------------------------------------------------------------
/bin/watcher.ts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ts-node
2 |
3 | import { exec } from 'child_process';
4 | import chokidar from 'chokidar';
5 | import path from 'path';
6 | import { contentComponentsMarkdownDir } from '../i18n';
7 |
8 | // Define the directory to watch
9 | const contentDir = path.join(process.cwd(), contentComponentsMarkdownDir);
10 |
11 | // Define the command to trigger
12 | const command = 'npm run generate-markdown-data';
13 |
14 | // Watch for changes in the directory
15 | const watcher = chokidar.watch(contentDir, {
16 | persistent: true,
17 | ignoreInitial: true,
18 | ignored: /(^|[\/\\])\../, // Ignore dot files
19 | awaitWriteFinish: {
20 | stabilityThreshold: 2000,
21 | pollInterval: 100
22 | }
23 | });
24 |
25 | // Function to run the command
26 | const runCommand = () => {
27 | exec(command, (error, stdout, stderr) => {
28 | if (error) {
29 | console.error(`Command execution failed: ${error.message}`);
30 | return;
31 | }
32 | if (stderr) {
33 | console.error(`stderr: ${stderr}`);
34 | return;
35 | }
36 | console.log(`stdout: ${stdout}`);
37 | });
38 | };
39 |
40 | // Set up the file watcher
41 | watcher
42 | .on('add', (path) => {
43 | console.log(`File ${path} has been added`);
44 | runCommand();
45 | })
46 | .on('unlink', (path) => {
47 | console.log(`File ${path} has been removed`);
48 | runCommand();
49 | });
50 |
51 | console.log(`Watching for changes in ${contentDir}`);
52 |
--------------------------------------------------------------------------------
/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "default",
4 | "rsc": true,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "tailwind.config.ts",
8 | "css": "app/globals.css",
9 | "baseColor": "slate",
10 | "cssVariables": true,
11 | "prefix": ""
12 | },
13 | "aliases": {
14 | "components": "@/components",
15 | "utils": "@/lib/utils"
16 | }
17 | }
--------------------------------------------------------------------------------
/components/frontend/google/desktop/FeaturedSnippets.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { Markdown } from "@/components/shared/markdown";
4 | import { cn } from "@/lib/utils";
5 | import { CrownIcon } from "lucide-react";
6 | import { useTranslations } from "next-intl";
7 | import {
8 | SerpFeaturedListSchema,
9 | SerpFeaturedNormalSchema,
10 | SerpFeaturedSnippetsSchema,
11 | type SerpFeaturedList,
12 | type SerpFeaturedNormal,
13 | type SerpFeaturedSnippets
14 | } from "serping/zod/google/desktop-serp";
15 |
16 | const List =({item, className}:{item: SerpFeaturedList, className?: string;})=>{
17 | return (
18 |
19 |
20 | {item.snippet_title &&
{item.snippet_title}
}
21 |
22 | {item.snippet_list?.map(obj => - {obj}
)}
23 |
24 |
25 | {item.images &&

}
26 |
27 | )
28 | }
29 |
30 | const Normal =({item, className}:{item: SerpFeaturedNormal, className?: string;})=>{
31 | return (
32 |
33 |
34 | {item.images &&

}
35 |
36 | )
37 | }
38 |
39 | export function FeaturedSnippets({original, className}:{original: SerpFeaturedSnippets, className?: string;}){
40 | const t = useTranslations();
41 |
42 | const data = SerpFeaturedSnippetsSchema.parse(original);
43 | const Content =()=>{
44 | if(original.featured_snippets.type === "featured_list"){
45 | const featuredList = SerpFeaturedListSchema.parse(data.featured_snippets);
46 | return
47 | }else{
48 | const featuredNormal= SerpFeaturedNormalSchema.parse(data.featured_snippets);
49 | return
50 | }
51 | }
52 |
53 | return (
54 |
55 |
56 |
57 |
58 | )
59 | }
--------------------------------------------------------------------------------
/components/frontend/google/desktop/InlineImages.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { cn } from "@/lib/utils";
4 | import { ImageIcon } from "lucide-react";
5 | import { useTranslations } from "next-intl";
6 | import type { SerpInlineImages } from "serping/zod/google/desktop-serp";
7 | import { TypeTitle } from "../shared/TypeTitle";
8 |
9 | export function InlineImages({original, className}:{original: SerpInlineImages, className?: string;}){
10 | const collection = original.collection;
11 | const t = useTranslations();
12 | return (
13 |
14 |
15 |
16 | {collection.map(image =>
17 | -
18 | {image.thumbnail === "imageBase64" ? :
19 |
20 |

21 |
22 | }
23 |
24 | )}
25 |
26 |
27 | )
28 | }
--------------------------------------------------------------------------------
/components/frontend/google/desktop/InlineVideos.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { cn } from "@/lib/utils";
4 | import { VideoIcon } from "lucide-react";
5 | import { useTranslations } from "next-intl";
6 | import type { SerpInlineVideos, SerpVideo } from "serping/zod/google/desktop-serp";
7 | import { TypeTitle } from "../shared/TypeTitle";
8 |
9 | export function InlineVideos({original, className}:{original: SerpInlineVideos, className?: string;}){
10 | const videos = original.inline_videos;
11 | const t = useTranslations();
12 | return (
13 |
14 |
15 |
16 | {videos.map(video =>
17 | -
18 | {video.thumbnail === "imageBase64" ? :
19 | <>
20 |
21 |

22 |
{video.duration}
23 |
24 |
25 |
28 |
{video.source.creator}
29 |
{video.date}
30 |
31 | >
32 | }
33 |
34 | )}
35 |
36 |
37 | )
38 | }
39 |
40 | // TODO: Video
41 | export function SerpVideo({original, className}:{original: SerpVideo, className?: string;}){
42 | return (
43 |
44 | {original.title}
45 |
46 | )
47 | }
--------------------------------------------------------------------------------
/components/frontend/google/desktop/PeopleAlsoAsk.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { cn } from "@/lib/utils";
4 | import { ExternalLinkIcon } from "lucide-react";
5 | import { useTranslations } from "next-intl";
6 | import Link from "next/link";
7 | import type { SerpPeopleAlsoAsk } from "serping/zod/google/desktop-serp";
8 | import { FilterUrl } from "../../google/shared/FilterUrl";
9 | import { TypeTitle } from "../shared/TypeTitle";
10 | export function PeopleAlsoAsk({
11 | original,
12 | className,
13 | filterUrl
14 | }:{
15 | original: SerpPeopleAlsoAsk,
16 | className?: string;
17 | filterUrl?: string;
18 | }){
19 | const t = useTranslations();
20 |
21 | return (
22 |
23 |
24 |
25 | {original.people_also_ask.map((item, index) =>
26 | -
27 |
28 |
29 | {item.question} {item.source && }
30 |
31 | {item.source &&
32 |
33 | }
34 |
35 |
36 | )}
37 |
38 |
39 | )
40 | }
--------------------------------------------------------------------------------
/components/frontend/google/desktop/Recipes.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { cn } from "@/lib/utils";
4 | import { ImageIcon } from "lucide-react";
5 | import { useTranslations } from "next-intl";
6 | import type { SerpRecipes } from "serping/zod/google/desktop-serp";
7 | import { FilterUrl } from "../shared/FilterUrl";
8 | import { TypeTitle } from "../shared/TypeTitle";
9 |
10 | export function Recipes({original, className, filterUrl}:{original: SerpRecipes, className?: string; filterUrl?: string;}){
11 | const recipes = original.recipes;
12 | const t = useTranslations();
13 | return (
14 |
15 |
16 |
17 | {recipes.map(item =>
18 | -
19 | {item.thumbnail === "imageBase64" ? :
20 | <>
21 |
22 |
23 |

24 |
25 |
26 |
29 |
{item.total_time}
30 |
{item.ingredients.join(", ")}
31 |
32 |
33 |
36 | >
37 | }
38 |
39 | )}
40 |
41 |
42 | )
43 | }
--------------------------------------------------------------------------------
/components/frontend/google/desktop/RelatedSearches.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { cn } from "@/lib/utils";
4 | import { useTranslations } from "next-intl";
5 | import { SerpRelatedNormalSchema, type SerpRelatedSearches } from "serping/zod/google/desktop-serp";
6 | import { TypeTitle } from "../shared/TypeTitle";
7 |
8 | export function RelatedSearches({original, className}:{original: SerpRelatedSearches[], className?: string;}){
9 | const t = useTranslations();
10 | // TODO: other types
11 | const Item =({item}:{item: SerpRelatedSearches})=>{
12 | switch(item.type){
13 | case "normal":{
14 | const data = SerpRelatedNormalSchema.parse(item);
15 | return (
16 |
17 | {data.searches.map((value, index) =>
18 | -
19 | {value}
20 |
21 | )}
22 |
23 | )
24 | }
25 | case "videos":
26 | return <>>
27 | case "people_also_search_for":
28 | return <>>
29 | case "near":
30 | return <>>
31 | default:
32 | return <>>;
33 | }
34 | }
35 |
36 |
37 | return (
38 |
39 |
40 | {original.map(item => - )}
41 |
42 | )
43 | }
--------------------------------------------------------------------------------
/components/frontend/google/desktop/ThinksToKnow.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { cn } from "@/lib/utils";
4 | import { ChevronDown, ChevronUp } from "lucide-react";
5 | import { useTranslations } from "next-intl";
6 | import { useState } from "react";
7 | import { SerpThingsToKnowListingSchema, SerpThingsToKnowNormal, type SerpThingsToKnow, type SerpThingsToKnowListing } from "serping/zod/google/desktop-serp";
8 | import { FilterUrl } from "../shared/FilterUrl";
9 | import { TypeTitle } from "../shared/TypeTitle";
10 |
11 |
12 | const Listing =({item}:{ item: SerpThingsToKnowListing })=>{
13 |
14 | return(
15 |
16 | )
17 | }
18 |
19 | const Normal =({item}:{ item: SerpThingsToKnowNormal })=>{
20 |
21 | return(
22 |
23 | )
24 | }
25 |
26 |
27 |
28 | const Heading = ({
29 | heading
30 | } :{
31 | heading:{
32 | primary: string;
33 | secondary: string;
34 | }
35 | })=>{
36 | return(
37 |
38 |
39 | {heading.primary}
40 |
41 |
42 | {heading.secondary}
43 |
44 |
45 | )
46 | }
47 |
48 | export function ThinksToKnow({original, className, filterUrl}:{original: SerpThingsToKnow, className?: string; filterUrl?: string;}){
49 | const t = useTranslations();
50 | const [open,setOpen] = useState(false);
51 |
52 | return (
53 |
54 |
55 |
56 | {original.things_to_know.map((item, index) => {
57 | const licn = cn("flex gap-3 py-2 flex-col", index > 3 ? `${open ? "" : "hidden"}` : "");
58 | const key = `things_to_know-${index}`;
59 | if( item.type === 'listing'){
60 | const data = SerpThingsToKnowListingSchema.parse(item);
61 | return(
62 | -
63 |
64 | {data.items.map(li=>
65 |
66 |
{li.source.title}
67 |
68 |
69 |
70 |
71 | )}
72 |
73 | )
74 | }else{
75 | const data = item as SerpThingsToKnowNormal
76 | return(
77 | -
78 |
79 | {data.source &&
80 |
{data.source.title}
81 |
82 |
83 |
84 | }
85 |
86 | )
87 | }
88 | })}
89 | {original.things_to_know.length >= 4 && - setOpen(!open)}>
90 | {open ? : }
91 |
}
92 |
93 |
94 |
95 | )
96 | }
--------------------------------------------------------------------------------
/components/frontend/google/desktop/TopStories.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { cn } from "@/lib/utils";
4 | import { useTranslations } from "next-intl";
5 | import type { SerpTopStories } from "serping/zod/google/desktop-serp";
6 | import { TypeTitle } from "../shared/TypeTitle";
7 |
8 | export function TopStories({original, className}:{original: SerpTopStories, className?: string;}){
9 | const t = useTranslations();
10 | return (
11 |
12 |
13 | {original.top_stories.stories.map((item, index) =>
14 |
15 |
{item.heading}
16 |
30 |
31 | )}
32 |
33 | )
34 | }
--------------------------------------------------------------------------------
/components/frontend/google/desktop/Twitter.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { Card, CardContent } from "@/components/ui/card";
4 | import {
5 | Carousel,
6 | CarouselContent,
7 | CarouselItem,
8 | CarouselNext,
9 | CarouselPrevious,
10 | } from "@/components/ui/carousel";
11 | import { cn } from "@/lib/utils";
12 | import { useTranslations } from "next-intl";
13 | import ReactMarkdown from 'react-markdown';
14 | import type { SerpTwitter } from "serping/zod/google/desktop-serp";
15 | import { ItemSource } from "../shared/ItemSource";
16 | import { TypeTitle } from "../shared/TypeTitle";
17 | export function Twitter({original, className}:{original: SerpTwitter, className?: string;}){
18 | const t = useTranslations();
19 | return (
20 |
42 | )
43 | }
--------------------------------------------------------------------------------
/components/frontend/google/desktop/Video.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { ItemSource } from "@/frontend/google/shared/ItemSource";
4 | import { cn } from "@/lib/utils";
5 | import type { SerpVideo } from "serping/zod/google/desktop-serp";
6 | export function Video({original, className}:{original: SerpVideo, className?: string;}){
7 | return (
8 |
9 |
10 |

11 |
{original.duration}
12 |
13 |
14 |
15 |
{original.snippet}
16 |
17 |
18 | )
19 | }
--------------------------------------------------------------------------------
/components/frontend/google/desktop/index.tsx:
--------------------------------------------------------------------------------
1 | export * from './DownloadCsv'
2 | export * from './FeaturedSnippets'
3 | export * from './InlineImages'
4 | export * from './InlineVideos'
5 | export * from './LocalResults'
6 | export * from './PeopleAlsoAsk'
7 | export * from './Recipes'
8 | export * from './RelatedSearches'
9 | export * from './ThinksToKnow'
10 | export * from './TopStories'
11 | export * from './Twitter'
12 | export * from './Video'
13 |
14 |
--------------------------------------------------------------------------------
/components/frontend/google/shared/FilterUrl.tsx:
--------------------------------------------------------------------------------
1 |
2 | export const FilterUrl =({link, filter}:{link: string, filter?: string})=>{
3 | if(filter){
4 | return ${filter}`)}} />;
5 | }else{
6 | return link
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/components/frontend/google/shared/ItemNormal.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { Markdown } from "@/components/shared/markdown";
4 | import { cn } from "@/lib/utils";
5 | export function ItemNormal({
6 | item,
7 | className
8 | }:{
9 | item:{
10 | title: string;
11 | link: string;
12 | snippet: string;
13 | };
14 | className?: string;
15 | }){
16 | return(
17 |
21 | )
22 | }
--------------------------------------------------------------------------------
/components/frontend/google/shared/ItemSource.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { cn } from "@/lib/utils";
4 | import { SerpItemSource } from 'serping/zod/google/base';
5 | import { SiteIcon } from './SiteIcon';
6 | export function ItemSource({
7 | source,
8 | className
9 | }:{
10 | source: SerpItemSource;
11 | className?: string;
12 | }){
13 | return(
14 |
26 | )
27 | }
--------------------------------------------------------------------------------
/components/frontend/google/shared/SiteIcon.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { cn } from "@/lib/utils";
4 | export function SiteIcon({
5 | link,
6 | className
7 | }:{
8 | link: string;
9 | className?: string;
10 | }){
11 | const url = new URL(link);
12 | return
13 | }
--------------------------------------------------------------------------------
/components/frontend/google/shared/TypeTitle.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { cn } from "@/lib/utils";
4 | export function TypeTitle({title, className}:{title: string; className?: string;}){
5 | return {title}
6 | }
--------------------------------------------------------------------------------
/components/frontend/page/home/faqs.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import {
4 | Accordion,
5 | AccordionContent,
6 | AccordionItem,
7 | AccordionTrigger,
8 | } from "@/components/ui/accordion";
9 | import { TypographyUL } from "@/components/ui/typography";
10 | import ReactMarkdown from 'react-markdown';
11 |
12 | type Faq = {
13 | question: string;
14 | answer: string;
15 | }
16 | type ItemCF = ({faq,value}:{faq: Faq, value: string}) => React.ReactNode;
17 |
18 | export function Faqs({ faqs, title }:{ faqs: Faq[], title?: string;}){
19 |
20 | const Item: ItemCF = ({faq,value})=>{
21 | return (
22 |
23 | {faq.question}
24 |
25 | {children},
27 | a: ({ children, href }) => {children}
28 | }}
29 |
30 | >{faq.answer}
31 |
32 |
33 | )
34 | }
35 | const items = faqs.map((item,index) => )
36 | return (
37 | <>
38 | {title && {title}
}
39 | {items}
40 | >
41 | )
42 | }
--------------------------------------------------------------------------------
/components/frontend/page/home/landing.tsx:
--------------------------------------------------------------------------------
1 |
2 | "use client"
3 |
4 | import { Markdown } from '@/components/shared/markdown';
5 | import { cn } from "@/lib/utils";
6 | import { useTranslations } from "next-intl";
7 | import { Faqs } from './faqs';
8 |
9 | export function Landing({className, block2}:{ className?: string; block2?: string;}){
10 | const t = useTranslations();
11 | const faqs = [
12 | {
13 | question: t('frontend.home.faq.qa1.question'),
14 | answer: t('frontend.home.faq.qa1.answer')
15 | },
16 | {
17 | question: t('frontend.home.faq.qa2.question'),
18 | answer: t('frontend.home.faq.qa2.answer')
19 | },
20 | {
21 | question: t('frontend.home.faq.qa3.question'),
22 | answer: t('frontend.home.faq.qa3.answer')
23 | },
24 | {
25 | question: t('frontend.home.faq.qa4.question'),
26 | answer: t('frontend.home.faq.qa4.answer')
27 | },
28 | {
29 | question: t('frontend.home.faq.qa5.question'),
30 | answer: t('frontend.home.faq.qa5.answer')
31 | },
32 | ]
33 | return(
34 |
35 | {block2 && }
36 |
37 |
38 | )
39 | }
--------------------------------------------------------------------------------
/components/frontend/page/home/main.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import { Skeleton } from "@/components/ui/skeleton";
4 | import { DeviceType } from "@/config";
5 | import { SerpForm } from "@/frontend/page/home/form";
6 | import apiClient from "@/lib/api";
7 | import { cn } from "@/lib/utils";
8 | import { type HomeFormValues } from "@/schema/index";
9 | import { ChangeEvent, useEffect, useState } from "react";
10 | import { SerpJsonSchema, type SerpJSON } from "serping/zod/google/desktop-serp";
11 | import { Landing as LandingPage } from "./landing";
12 | import { Results } from "./results";
13 | import { Status } from "./status";
14 |
15 | export function Main({
16 | params,
17 | markdownContents
18 | }: Readonly<{
19 | params: { locale: string; };
20 | markdownContents: Record;
21 | }>) {
22 | const locale = params.locale;
23 | const { block1, block2 } = markdownContents;
24 | const defaultValues: HomeFormValues = {
25 | query: "",
26 | locale: locale === "zh" ? "zh-Hans" : locale,
27 | country: "us" ,
28 | location: "",
29 | device: "desktop" as DeviceType,
30 | snapshot: "off"
31 | }
32 | const [searchParams, setSearchParams] = useState(defaultValues);
33 | const [results, setResults] = useState(null);
34 | const [loading, setLoading] = useState(false);
35 | const [preview, setPreview] = useState(false);
36 | const [landing, setLanding] = useState(true);
37 | const [filterUrl, setFilterUrl] = useState("");
38 |
39 | useEffect(()=>{
40 | if(searchParams.query){
41 | const params = {
42 | q: searchParams.query,
43 | hl: searchParams.locale,
44 | gl: searchParams.country,
45 | location: searchParams.location,
46 | snapshot: searchParams.snapshot,
47 | thumbnail: "on",
48 | num: 100,
49 | // device: searchParams.device,
50 | }
51 | setLoading(true);
52 | apiClient.post('/google/serp', { body: JSON.stringify(params) })
53 | .then((data) => {
54 | setResults(SerpJsonSchema.parse(data));
55 | setLoading(false);
56 | })
57 | .catch((error) => {
58 | console.error("error", error);
59 | setLoading(false);
60 | });
61 | }
62 | }, [searchParams]);
63 |
64 | const SkeletonItem =()=>{
65 | return (
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | )
74 | }
75 |
76 | const SkeletonList =({num}:{num: number})=>{
77 | const items = [];
78 | for (let i = 0; i < num; i++) {
79 | items.push()
80 | }
81 | return items;
82 | }
83 |
84 | const onSubmit =({values}:{values: HomeFormValues})=>{
85 | if(landing) setLanding(false);
86 | setSearchParams(values)
87 | }
88 |
89 | const onCheckedChange=(checked: boolean)=>{
90 | setPreview(checked)
91 | }
92 |
93 | const filterOnChange =(e: ChangeEvent)=>{
94 | setFilterUrl(e.target.value)
95 | }
96 |
97 | return (
98 |
99 |
100 |
101 |
102 |
103 | {!landing && }
104 | {landing && }
105 | {loading && }
106 | {!loading && searchParams.query && results && }
107 |
108 |
109 | );
110 | }
111 |
--------------------------------------------------------------------------------
/components/frontend/page/home/status.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import { Input } from "@/components/ui/input";
4 | import { Switch } from "@/components/ui/switch";
5 | import { countries } from "@/country";
6 | import { HomeFormValues } from "@/schema";
7 | import {
8 | Camera,
9 | Globe,
10 | Monitor,
11 | Smartphone
12 | } from "lucide-react";
13 | import { useTranslations } from "next-intl";
14 | import { ChangeEvent } from "react";
15 | import { SerpJSON } from "serping/zod/google/desktop-serp";
16 | import { DownloadCsv } from "../../google/desktop";
17 |
18 | export function Status({
19 | searchUrl,
20 | snapshotId,
21 | searchParams,
22 | loading,
23 | onCheckedChange,
24 | results,
25 | filterOnChange
26 | }: {
27 | searchParams: HomeFormValues;
28 | onCheckedChange?: ( checked: boolean )=> void;
29 | searchUrl?: string;
30 | snapshotId?: string;
31 | results: SerpJSON | null;
32 | loading: boolean;
33 | filterOnChange?: (e: ChangeEvent) => void;
34 | }){
35 | const t = useTranslations();
36 | const devicesIcons = {
37 | "desktop": ,
38 | "mobile":
39 | }
40 | const country = countries.find(item => item.code === searchParams.country);
41 |
42 | const onSwitchChange =(checked: boolean)=>{
43 | if(onCheckedChange) onCheckedChange(checked);
44 | }
45 | return(
46 |
47 | {searchParams.query &&
{t('frontend.home.results_for', { query: searchParams.query } )}
}
48 |
49 |
56 |
57 |
58 | {t('frontend.serp.url')}
59 | filterOnChange? filterOnChange(e) : null} />
60 |
61 |
62 | {t("frontend.home.views.preview")}
63 |
64 |
65 |
66 |
67 | )
68 | }
69 |
--------------------------------------------------------------------------------
/components/frontend/shared/footer.tsx:
--------------------------------------------------------------------------------
1 | import { appConfig } from "@/config";
2 |
3 | export function Footer() {
4 | return (
5 |
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/components/frontend/shared/header.tsx:
--------------------------------------------------------------------------------
1 |
2 | "use client"
3 |
4 | import { LocaleSwitch } from "@/components/shared/locale-switch";
5 | import { ModeToggle } from "@/components/shared/mode-toggle";
6 | import { cn } from "@/lib/utils";
7 | import { useEffect, useState } from "react";
8 | import { useDebounceCallback } from "usehooks-ts";
9 | import { NavBar } from "./nav-bar";
10 |
11 | export function Header() {
12 | const [isTop, setIsTop] = useState(true);
13 | const debouncedScroll = useDebounceCallback(
14 | () => {
15 | setIsTop(window.scrollY < 20);
16 | },
17 | 150,
18 | {
19 | maxWait: 150,
20 | },
21 | );
22 |
23 | useEffect(() => {
24 | window.addEventListener("scroll", debouncedScroll);
25 | debouncedScroll();
26 | return () => {
27 | window.removeEventListener("scroll", debouncedScroll);
28 | };
29 | }, [debouncedScroll]);
30 |
31 | return(
32 |
42 | )
43 | }
--------------------------------------------------------------------------------
/components/frontend/shared/nav-bar.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from "@/components/ui/button";
2 | import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet";
3 | import { Link } from "@/lib/i18n";
4 |
5 | import {
6 | Menu
7 | } from "lucide-react";
8 | import Image from "next/image";
9 | export function NavBar() {
10 | const memu = [
11 | {
12 | name: "SERP Checking",
13 | href: "/"
14 | }
15 | ];
16 |
17 | const Logo =()=>{
18 | return(
19 |
23 |
24 | SERP Checking
25 |
26 | )
27 | }
28 | return (
29 |
30 |
42 |
43 |
44 |
52 |
53 |
54 |
66 |
67 |
68 |
69 | );
70 | }
71 |
--------------------------------------------------------------------------------
/components/frontend/shared/not-found.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { Button } from "@/components/ui/button";
4 | import { Link } from "@/lib/i18n";
5 | import { UndoIcon } from "lucide-react";
6 | import { useTranslations } from "next-intl";
7 |
8 | export function NotFound() {
9 | const t = useTranslations();
10 | return (
11 |
12 |
404
13 |
{t("frontend.page_not_found")}
14 |
15 |
20 |
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/components/frontend/shared/top.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import { Button } from "@/components/ui/button";
4 | import { cn } from "@/lib/utils";
5 | import { ChevronUpIcon } from "lucide-react";
6 | import { useEffect, useState } from "react";
7 | import { useDebounceCallback } from "usehooks-ts";
8 |
9 | export function Top() {
10 | const scrollTo = () => {
11 | window.scrollTo({
12 | top: 0,
13 | behavior: 'smooth',
14 | });
15 | };
16 |
17 | const [show, setShow] = useState(true);
18 | const debouncedScroll = useDebounceCallback(
19 | () => {
20 | setShow(window.scrollY > 100);
21 | },
22 | 150,
23 | {
24 | maxWait: 150,
25 | },
26 | );
27 |
28 | useEffect(() => {
29 | window.addEventListener("scroll", debouncedScroll);
30 | debouncedScroll();
31 | return () => {
32 | window.removeEventListener("scroll", debouncedScroll);
33 | };
34 | }, [debouncedScroll]);
35 |
36 | return (
37 |
38 |
41 |
42 | );
43 | }
44 |
--------------------------------------------------------------------------------
/components/shared/locale-switch.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import { Button } from "@/components/ui/button"
4 | import {
5 | DropdownMenu,
6 | DropdownMenuContent,
7 | DropdownMenuRadioGroup,
8 | DropdownMenuRadioItem,
9 | DropdownMenuTrigger,
10 | } from "@/components/ui/dropdown-menu"
11 | import { appConfig, type LocaleType } from "@/config"
12 | import { usePathname } from "@/lib/i18n"
13 | import { LanguagesIcon } from "lucide-react"
14 | import { useLocale } from "next-intl"
15 | import { useRouter, useSearchParams } from "next/navigation"
16 | import { useState } from "react"
17 |
18 | export function LocaleSwitch() {
19 | const router = useRouter();
20 | const currentLocale = useLocale() as LocaleType;
21 | const [locale, setLocale] = useState(currentLocale);
22 | const { labels, locales } = appConfig.i18n;
23 | const pathname = usePathname();
24 | const searchParams = useSearchParams();
25 | return (
26 |
27 |
28 |
31 |
32 |
33 | {
36 | setLocale(value as LocaleType);
37 | router.replace(`/${value}/${pathname}?${searchParams.toString()}`);
38 | }}
39 | >
40 | {locales.map((locale) => {
41 | return (
42 |
43 | {locale in labels
44 | ? labels[locale as keyof typeof labels]
45 | : locale}
46 |
47 | );
48 | })}
49 |
50 |
51 |
52 | )
53 | }
54 |
--------------------------------------------------------------------------------
/components/shared/markdown.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from '@/lib/utils';
2 | import ReactMarkdown from 'react-markdown';
3 | import rehypeRaw from 'rehype-raw';
4 | import remarkGfm from 'remark-gfm';
5 | import {
6 | TypographyBlockquote,
7 | TypographyH1,
8 | TypographyH2,
9 | TypographyH3,
10 | TypographyH4,
11 | TypographyInlineCode,
12 | TypographyOL,
13 | TypographyP,
14 | TypographySmall,
15 | TypographyUL
16 | } from '../ui/typography';
17 |
18 | export function Markdown({
19 | content,
20 | className,
21 | classNames,
22 | markdownClassName
23 | }:{
24 | content: string;
25 | className?: string;
26 | classNames?:{
27 | h1?: string;
28 | h2?: string;
29 | h3?: string;
30 | h4?: string;
31 | p?: string;
32 | blockquote?: string;
33 | ul?: string;
34 | ol?: string;
35 | code?: string;
36 | small?: string;
37 | };
38 | markdownClassName?: string;
39 | } ){
40 | return(
41 |
42 | {children},
47 | h2: ({ children }) => {children},
48 | h3: ({ children }) => {children},
49 | h4: ({ children }) => {children},
50 | p: ({ children }) => {children},
51 | blockquote: ({ children }) => {children},
52 | ul: ({ children }) => {children},
53 | ol: ({ children }) => {children},
54 | code: ({ children }) => {children},
55 | small: ({ children }) => {children},
56 | }}
57 | className={markdownClassName}
58 | >
59 | {content}
60 |
61 |
62 | )
63 | }
--------------------------------------------------------------------------------
/components/shared/mode-toggle.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import { Moon, Sun } from "lucide-react"
4 | import { useTheme } from "next-themes"
5 |
6 | import { Button } from "@/components/ui/button"
7 | import {
8 | DropdownMenu,
9 | DropdownMenuContent,
10 | DropdownMenuItem,
11 | DropdownMenuTrigger,
12 | } from "@/components/ui/dropdown-menu"
13 | import { useTranslations } from "next-intl"
14 |
15 | export function ModeToggle() {
16 | const { setTheme } = useTheme()
17 | const t = useTranslations();
18 |
19 | return (
20 |
21 |
22 |
27 |
28 |
29 | setTheme("light")}>
30 | {t("menu.light")}
31 |
32 | setTheme("dark")}>
33 | {t("menu.dark")}
34 |
35 | setTheme("system")}>
36 | {t("menu.system")}
37 |
38 |
39 |
40 | )
41 | }
42 |
--------------------------------------------------------------------------------
/components/ui/accordion.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import * as AccordionPrimitive from "@radix-ui/react-accordion"
5 | import { ChevronDown } from "lucide-react"
6 |
7 | import { cn } from "@/lib/utils"
8 |
9 | const Accordion = AccordionPrimitive.Root
10 |
11 | const AccordionItem = React.forwardRef<
12 | React.ElementRef,
13 | React.ComponentPropsWithoutRef
14 | >(({ className, ...props }, ref) => (
15 |
20 | ))
21 | AccordionItem.displayName = "AccordionItem"
22 |
23 | const AccordionTrigger = React.forwardRef<
24 | React.ElementRef,
25 | React.ComponentPropsWithoutRef
26 | >(({ className, children, ...props }, ref) => (
27 |
28 | svg]:rotate-180",
32 | className
33 | )}
34 | {...props}
35 | >
36 | {children}
37 |
38 |
39 |
40 | ))
41 | AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName
42 |
43 | const AccordionContent = React.forwardRef<
44 | React.ElementRef,
45 | React.ComponentPropsWithoutRef
46 | >(({ className, children, ...props }, ref) => (
47 |
52 | {children}
53 |
54 | ))
55 |
56 | AccordionContent.displayName = AccordionPrimitive.Content.displayName
57 |
58 | export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
59 |
--------------------------------------------------------------------------------
/components/ui/avatar.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import * as AvatarPrimitive from "@radix-ui/react-avatar"
5 |
6 | import { cn } from "@/lib/utils"
7 |
8 | const Avatar = React.forwardRef<
9 | React.ElementRef,
10 | React.ComponentPropsWithoutRef
11 | >(({ className, ...props }, ref) => (
12 |
20 | ))
21 | Avatar.displayName = AvatarPrimitive.Root.displayName
22 |
23 | const AvatarImage = React.forwardRef<
24 | React.ElementRef,
25 | React.ComponentPropsWithoutRef
26 | >(({ className, ...props }, ref) => (
27 |
32 | ))
33 | AvatarImage.displayName = AvatarPrimitive.Image.displayName
34 |
35 | const AvatarFallback = React.forwardRef<
36 | React.ElementRef,
37 | React.ComponentPropsWithoutRef
38 | >(({ className, ...props }, ref) => (
39 |
47 | ))
48 | AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName
49 |
50 | export { Avatar, AvatarImage, AvatarFallback }
51 |
--------------------------------------------------------------------------------
/components/ui/badge.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import { cva, type VariantProps } from "class-variance-authority"
3 |
4 | import { cn } from "@/lib/utils"
5 |
6 | const badgeVariants = cva(
7 | "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
8 | {
9 | variants: {
10 | variant: {
11 | default:
12 | "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
13 | secondary:
14 | "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
15 | destructive:
16 | "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
17 | outline: "text-foreground",
18 | },
19 | },
20 | defaultVariants: {
21 | variant: "default",
22 | },
23 | }
24 | )
25 |
26 | export interface BadgeProps
27 | extends React.HTMLAttributes,
28 | VariantProps {}
29 |
30 | function Badge({ className, variant, ...props }: BadgeProps) {
31 | return (
32 |
33 | )
34 | }
35 |
36 | export { Badge, badgeVariants }
37 |
--------------------------------------------------------------------------------
/components/ui/button.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from "@/lib/utils"
2 | import { Slot } from "@radix-ui/react-slot"
3 | import { cva, type VariantProps } from "class-variance-authority"
4 | import { LoaderIcon } from "lucide-react"
5 | import * as React from "react"
6 |
7 | const buttonVariants = cva(
8 | "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
9 | {
10 | variants: {
11 | variant: {
12 | default: "bg-primary text-primary-foreground hover:bg-primary/90",
13 | destructive:
14 | "bg-destructive text-destructive-foreground hover:bg-destructive/90",
15 | outline:
16 | "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
17 | secondary:
18 | "bg-secondary text-secondary-foreground hover:bg-secondary/80",
19 | ghost: "hover:bg-accent hover:text-accent-foreground",
20 | link: "text-primary underline-offset-4 hover:underline",
21 | },
22 | size: {
23 | default: "h-10 px-4 py-2",
24 | sm: "h-9 rounded-md px-3",
25 | lg: "h-11 rounded-md px-8",
26 | icon: "h-10 w-10",
27 | },
28 | },
29 | defaultVariants: {
30 | variant: "default",
31 | size: "default",
32 | },
33 | }
34 | )
35 |
36 | export interface ButtonProps
37 | extends React.ButtonHTMLAttributes,
38 | VariantProps {
39 | asChild?: boolean;
40 | loading?: boolean;
41 | }
42 |
43 | const Button = React.forwardRef(
44 | ({ className, variant, size, asChild = false, loading, disabled, children, ...props }, ref) => {
45 | const Comp = asChild ? Slot : "button"
46 | return (
47 |
53 | {loading ? : children}
54 |
55 | )
56 | }
57 | )
58 | Button.displayName = "Button"
59 |
60 | export { Button, buttonVariants }
61 |
--------------------------------------------------------------------------------
/components/ui/card.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 |
3 | import { cn } from "@/lib/utils"
4 |
5 | const Card = React.forwardRef<
6 | HTMLDivElement,
7 | React.HTMLAttributes
8 | >(({ className, ...props }, ref) => (
9 |
17 | ))
18 | Card.displayName = "Card"
19 |
20 | const CardHeader = React.forwardRef<
21 | HTMLDivElement,
22 | React.HTMLAttributes
23 | >(({ className, ...props }, ref) => (
24 |
29 | ))
30 | CardHeader.displayName = "CardHeader"
31 |
32 | const CardTitle = React.forwardRef<
33 | HTMLParagraphElement,
34 | React.HTMLAttributes
35 | >(({ className, ...props }, ref) => (
36 |
44 | ))
45 | CardTitle.displayName = "CardTitle"
46 |
47 | const CardDescription = React.forwardRef<
48 | HTMLParagraphElement,
49 | React.HTMLAttributes
50 | >(({ className, ...props }, ref) => (
51 |
56 | ))
57 | CardDescription.displayName = "CardDescription"
58 |
59 | const CardContent = React.forwardRef<
60 | HTMLDivElement,
61 | React.HTMLAttributes
62 | >(({ className, ...props }, ref) => (
63 |
64 | ))
65 | CardContent.displayName = "CardContent"
66 |
67 | const CardFooter = React.forwardRef<
68 | HTMLDivElement,
69 | React.HTMLAttributes
70 | >(({ className, ...props }, ref) => (
71 |
76 | ))
77 | CardFooter.displayName = "CardFooter"
78 |
79 | export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
80 |
--------------------------------------------------------------------------------
/components/ui/dialog.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import * as DialogPrimitive from "@radix-ui/react-dialog"
5 | import { X } from "lucide-react"
6 |
7 | import { cn } from "@/lib/utils"
8 |
9 | const Dialog = DialogPrimitive.Root
10 |
11 | const DialogTrigger = DialogPrimitive.Trigger
12 |
13 | const DialogPortal = DialogPrimitive.Portal
14 |
15 | const DialogClose = DialogPrimitive.Close
16 |
17 | const DialogOverlay = React.forwardRef<
18 | React.ElementRef,
19 | React.ComponentPropsWithoutRef
20 | >(({ className, ...props }, ref) => (
21 |
29 | ))
30 | DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
31 |
32 | const DialogContent = React.forwardRef<
33 | React.ElementRef,
34 | React.ComponentPropsWithoutRef
35 | >(({ className, children, ...props }, ref) => (
36 |
37 |
38 |
46 | {children}
47 |
48 |
49 | Close
50 |
51 |
52 |
53 | ))
54 | DialogContent.displayName = DialogPrimitive.Content.displayName
55 |
56 | const DialogHeader = ({
57 | className,
58 | ...props
59 | }: React.HTMLAttributes) => (
60 |
67 | )
68 | DialogHeader.displayName = "DialogHeader"
69 |
70 | const DialogFooter = ({
71 | className,
72 | ...props
73 | }: React.HTMLAttributes) => (
74 |
81 | )
82 | DialogFooter.displayName = "DialogFooter"
83 |
84 | const DialogTitle = React.forwardRef<
85 | React.ElementRef,
86 | React.ComponentPropsWithoutRef
87 | >(({ className, ...props }, ref) => (
88 |
96 | ))
97 | DialogTitle.displayName = DialogPrimitive.Title.displayName
98 |
99 | const DialogDescription = React.forwardRef<
100 | React.ElementRef,
101 | React.ComponentPropsWithoutRef
102 | >(({ className, ...props }, ref) => (
103 |
108 | ))
109 | DialogDescription.displayName = DialogPrimitive.Description.displayName
110 |
111 | export {
112 | Dialog,
113 | DialogPortal,
114 | DialogOverlay,
115 | DialogClose,
116 | DialogTrigger,
117 | DialogContent,
118 | DialogHeader,
119 | DialogFooter,
120 | DialogTitle,
121 | DialogDescription,
122 | }
123 |
--------------------------------------------------------------------------------
/components/ui/form.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as LabelPrimitive from "@radix-ui/react-label"
4 | import { Slot } from "@radix-ui/react-slot"
5 | import * as React from "react"
6 | import {
7 | Controller,
8 | ControllerProps,
9 | FieldPath,
10 | FieldValues,
11 | FormProvider,
12 | useFormContext,
13 | } from "react-hook-form"
14 |
15 | import { Label } from "@/components/ui/label"
16 | import { cn } from "@/lib/utils"
17 |
18 | const Form = FormProvider
19 |
20 | type FormFieldContextValue<
21 | TFieldValues extends FieldValues = FieldValues,
22 | TName extends FieldPath = FieldPath
23 | > = {
24 | name: TName
25 | }
26 |
27 | const FormFieldContext = React.createContext(
28 | {} as FormFieldContextValue
29 | )
30 |
31 | const FormField = <
32 | TFieldValues extends FieldValues = FieldValues,
33 | TName extends FieldPath = FieldPath
34 | >({
35 | ...props
36 | }: ControllerProps) => {
37 | return (
38 |
39 |
40 |
41 | )
42 | }
43 |
44 | const useFormField = () => {
45 | const fieldContext = React.useContext(FormFieldContext)
46 | const itemContext = React.useContext(FormItemContext)
47 | const { getFieldState, formState } = useFormContext()
48 |
49 | const fieldState = getFieldState(fieldContext.name, formState)
50 |
51 | if (!fieldContext) {
52 | throw new Error("useFormField should be used within ")
53 | }
54 |
55 | const { id } = itemContext
56 |
57 | return {
58 | id,
59 | name: fieldContext.name,
60 | formItemId: `${id}-form-item`,
61 | formDescriptionId: `${id}-form-item-description`,
62 | formMessageId: `${id}-form-item-message`,
63 | ...fieldState,
64 | }
65 | }
66 |
67 | type FormItemContextValue = {
68 | id: string
69 | }
70 |
71 | const FormItemContext = React.createContext(
72 | {} as FormItemContextValue
73 | )
74 |
75 | const FormItem = React.forwardRef<
76 | HTMLDivElement,
77 | React.HTMLAttributes& { nospace?: boolean; }
78 | >(({ nospace = false, className, ...props }, ref) => {
79 | const id = React.useId()
80 |
81 | return (
82 |
83 |
84 |
85 | )
86 | })
87 | FormItem.displayName = "FormItem"
88 |
89 | const FormLabel = React.forwardRef<
90 | React.ElementRef,
91 | React.ComponentPropsWithoutRef
92 | >(({ className, ...props }, ref) => {
93 | const { error, formItemId } = useFormField()
94 |
95 | return (
96 |
102 | )
103 | })
104 | FormLabel.displayName = "FormLabel"
105 |
106 | const FormControl = React.forwardRef<
107 | React.ElementRef,
108 | React.ComponentPropsWithoutRef
109 | >(({ ...props }, ref) => {
110 | const { error, formItemId, formDescriptionId, formMessageId } = useFormField()
111 |
112 | return (
113 |
124 | )
125 | })
126 | FormControl.displayName = "FormControl"
127 |
128 | const FormDescription = React.forwardRef<
129 | HTMLParagraphElement,
130 | React.HTMLAttributes
131 | >(({ className, ...props }, ref) => {
132 | const { formDescriptionId } = useFormField()
133 |
134 | return (
135 |
141 | )
142 | })
143 | FormDescription.displayName = "FormDescription"
144 |
145 | const FormMessage = React.forwardRef<
146 | HTMLParagraphElement,
147 | React.HTMLAttributes
148 | >(({ className, children, ...props }, ref) => {
149 | const { error, formMessageId } = useFormField()
150 | const body = error ? String(error?.message) : children
151 |
152 | if (!body) {
153 | return null
154 | }
155 |
156 | return (
157 |
163 | {body}
164 |
165 | )
166 | })
167 | FormMessage.displayName = "FormMessage"
168 |
169 | export {
170 | Form, FormControl,
171 | FormDescription, FormField, FormItem,
172 | FormLabel, FormMessage, useFormField
173 | }
174 |
175 |
--------------------------------------------------------------------------------
/components/ui/input.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 |
3 | import { cn } from "@/lib/utils"
4 |
5 | export interface InputProps
6 | extends React.InputHTMLAttributes {}
7 |
8 | const Input = React.forwardRef(
9 | ({ className, type, ...props }, ref) => {
10 | return (
11 |
20 | )
21 | }
22 | )
23 | Input.displayName = "Input"
24 |
25 | export { Input }
26 |
--------------------------------------------------------------------------------
/components/ui/label.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import * as LabelPrimitive from "@radix-ui/react-label"
5 | import { cva, type VariantProps } from "class-variance-authority"
6 |
7 | import { cn } from "@/lib/utils"
8 |
9 | const labelVariants = cva(
10 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
11 | )
12 |
13 | const Label = React.forwardRef<
14 | React.ElementRef,
15 | React.ComponentPropsWithoutRef &
16 | VariantProps
17 | >(({ className, ...props }, ref) => (
18 |
23 | ))
24 | Label.displayName = LabelPrimitive.Root.displayName
25 |
26 | export { Label }
27 |
--------------------------------------------------------------------------------
/components/ui/popover.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import * as PopoverPrimitive from "@radix-ui/react-popover"
5 |
6 | import { cn } from "@/lib/utils"
7 |
8 | const Popover = PopoverPrimitive.Root
9 |
10 | const PopoverTrigger = PopoverPrimitive.Trigger
11 |
12 | const PopoverContent = React.forwardRef<
13 | React.ElementRef,
14 | React.ComponentPropsWithoutRef
15 | >(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
16 |
17 |
27 |
28 | ))
29 | PopoverContent.displayName = PopoverPrimitive.Content.displayName
30 |
31 | export { Popover, PopoverTrigger, PopoverContent }
32 |
--------------------------------------------------------------------------------
/components/ui/sheet.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import * as SheetPrimitive from "@radix-ui/react-dialog"
5 | import { cva, type VariantProps } from "class-variance-authority"
6 | import { X } from "lucide-react"
7 |
8 | import { cn } from "@/lib/utils"
9 |
10 | const Sheet = SheetPrimitive.Root
11 |
12 | const SheetTrigger = SheetPrimitive.Trigger
13 |
14 | const SheetClose = SheetPrimitive.Close
15 |
16 | const SheetPortal = SheetPrimitive.Portal
17 |
18 | const SheetOverlay = React.forwardRef<
19 | React.ElementRef,
20 | React.ComponentPropsWithoutRef
21 | >(({ className, ...props }, ref) => (
22 |
30 | ))
31 | SheetOverlay.displayName = SheetPrimitive.Overlay.displayName
32 |
33 | const sheetVariants = cva(
34 | "fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
35 | {
36 | variants: {
37 | side: {
38 | top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
39 | bottom:
40 | "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
41 | left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
42 | right:
43 | "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
44 | },
45 | },
46 | defaultVariants: {
47 | side: "right",
48 | },
49 | }
50 | )
51 |
52 | interface SheetContentProps
53 | extends React.ComponentPropsWithoutRef,
54 | VariantProps {}
55 |
56 | const SheetContent = React.forwardRef<
57 | React.ElementRef,
58 | SheetContentProps
59 | >(({ side = "right", className, children, ...props }, ref) => (
60 |
61 |
62 |
67 | {children}
68 |
69 |
70 | Close
71 |
72 |
73 |
74 | ))
75 | SheetContent.displayName = SheetPrimitive.Content.displayName
76 |
77 | const SheetHeader = ({
78 | className,
79 | ...props
80 | }: React.HTMLAttributes) => (
81 |
88 | )
89 | SheetHeader.displayName = "SheetHeader"
90 |
91 | const SheetFooter = ({
92 | className,
93 | ...props
94 | }: React.HTMLAttributes) => (
95 |
102 | )
103 | SheetFooter.displayName = "SheetFooter"
104 |
105 | const SheetTitle = React.forwardRef<
106 | React.ElementRef,
107 | React.ComponentPropsWithoutRef
108 | >(({ className, ...props }, ref) => (
109 |
114 | ))
115 | SheetTitle.displayName = SheetPrimitive.Title.displayName
116 |
117 | const SheetDescription = React.forwardRef<
118 | React.ElementRef,
119 | React.ComponentPropsWithoutRef
120 | >(({ className, ...props }, ref) => (
121 |
126 | ))
127 | SheetDescription.displayName = SheetPrimitive.Description.displayName
128 |
129 | export {
130 | Sheet,
131 | SheetPortal,
132 | SheetOverlay,
133 | SheetTrigger,
134 | SheetClose,
135 | SheetContent,
136 | SheetHeader,
137 | SheetFooter,
138 | SheetTitle,
139 | SheetDescription,
140 | }
141 |
--------------------------------------------------------------------------------
/components/ui/skeleton.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from "@/lib/utils"
2 |
3 | function Skeleton({
4 | className,
5 | ...props
6 | }: React.HTMLAttributes) {
7 | return (
8 |
12 | )
13 | }
14 |
15 | export { Skeleton }
16 |
--------------------------------------------------------------------------------
/components/ui/switch.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import * as SwitchPrimitives from "@radix-ui/react-switch"
5 |
6 | import { cn } from "@/lib/utils"
7 |
8 | const Switch = React.forwardRef<
9 | React.ElementRef,
10 | React.ComponentPropsWithoutRef
11 | >(({ className, ...props }, ref) => (
12 |
20 |
25 |
26 | ))
27 | Switch.displayName = SwitchPrimitives.Root.displayName
28 |
29 | export { Switch }
30 |
--------------------------------------------------------------------------------
/components/ui/table.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 |
3 | import { cn } from "@/lib/utils"
4 |
5 | const Table = React.forwardRef<
6 | HTMLTableElement,
7 | React.HTMLAttributes
8 | >(({ className, ...props }, ref) => (
9 |
16 | ))
17 | Table.displayName = "Table"
18 |
19 | const TableHeader = React.forwardRef<
20 | HTMLTableSectionElement,
21 | React.HTMLAttributes
22 | >(({ className, ...props }, ref) => (
23 |
24 | ))
25 | TableHeader.displayName = "TableHeader"
26 |
27 | const TableBody = React.forwardRef<
28 | HTMLTableSectionElement,
29 | React.HTMLAttributes
30 | >(({ className, ...props }, ref) => (
31 |
36 | ))
37 | TableBody.displayName = "TableBody"
38 |
39 | const TableFooter = React.forwardRef<
40 | HTMLTableSectionElement,
41 | React.HTMLAttributes
42 | >(({ className, ...props }, ref) => (
43 | tr]:last:border-b-0",
47 | className
48 | )}
49 | {...props}
50 | />
51 | ))
52 | TableFooter.displayName = "TableFooter"
53 |
54 | const TableRow = React.forwardRef<
55 | HTMLTableRowElement,
56 | React.HTMLAttributes
57 | >(({ className, ...props }, ref) => (
58 |
66 | ))
67 | TableRow.displayName = "TableRow"
68 |
69 | const TableHead = React.forwardRef<
70 | HTMLTableCellElement,
71 | React.ThHTMLAttributes
72 | >(({ className, ...props }, ref) => (
73 | |
81 | ))
82 | TableHead.displayName = "TableHead"
83 |
84 | const TableCell = React.forwardRef<
85 | HTMLTableCellElement,
86 | React.TdHTMLAttributes
87 | >(({ className, ...props }, ref) => (
88 | |
93 | ))
94 | TableCell.displayName = "TableCell"
95 |
96 | const TableCaption = React.forwardRef<
97 | HTMLTableCaptionElement,
98 | React.HTMLAttributes
99 | >(({ className, ...props }, ref) => (
100 |
105 | ))
106 | TableCaption.displayName = "TableCaption"
107 |
108 | export {
109 | Table,
110 | TableHeader,
111 | TableBody,
112 | TableFooter,
113 | TableHead,
114 | TableRow,
115 | TableCell,
116 | TableCaption,
117 | }
118 |
--------------------------------------------------------------------------------
/components/ui/toaster.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import {
4 | Toast,
5 | ToastClose,
6 | ToastDescription,
7 | ToastProvider,
8 | ToastTitle,
9 | ToastViewport,
10 | } from "@/components/ui/toast"
11 | import { useToast } from "@/components/ui/use-toast"
12 |
13 | export function Toaster() {
14 | const { toasts } = useToast()
15 |
16 | return (
17 |
18 | {toasts.map(function ({ id, title, description, action, ...props }) {
19 | return (
20 |
21 |
22 | {title && {title}}
23 | {description && (
24 | {description}
25 | )}
26 |
27 | {action}
28 |
29 |
30 | )
31 | })}
32 |
33 |
34 | )
35 | }
36 |
--------------------------------------------------------------------------------
/components/ui/typography.tsx:
--------------------------------------------------------------------------------
1 | import { HTMLAttributes } from 'react';
2 |
3 | const classNames ={
4 | h1: "scroll-m-20 text-2xl font-extrabold tracking-tight lg:text-3xl",
5 | h2: "scroll-m-20 pb-2 text-2xl font-semibold tracking-tight first:mt-0",
6 | h3: "scroll-m-20 text-xl font-semibold tracking-tight",
7 | h4: "scroll-m-20 text-base font-semibold tracking-tight",
8 | p: "leading-7 [&:not(:first-child)]:mt-6",
9 | blockquote: "mt-6 border-l-2 pl-6 italic",
10 | ul: "my-6 ml-6 [&>li]:mt-2",
11 | ol: "my-6 ml-6 [&>li]:mt-2",
12 | code: "relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold",
13 | lead: "text-xl text-muted-foreground",
14 | small: "text-sm font-medium leading-none",
15 | table:{
16 | root: "w-full",
17 | th: "border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right",
18 | tr: "m-0 border-t p-0 even:bg-muted",
19 | td: "border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right"
20 | }
21 | }
22 |
23 | export const TypographyH1 = ({ children, className, ...props }: HTMLAttributes & { children?: React.ReactNode }) => {
24 | return {children}
;
25 | };
26 |
27 | export const TypographyH2 = ({ children, className, ...props }: HTMLAttributes & { children?: React.ReactNode }) => {
28 | return {children}
;
29 | };
30 | export const TypographyH3 = ({ children, className, ...props }: HTMLAttributes & { children?: React.ReactNode }) => {
31 | return {children}
;
32 | };
33 |
34 | export const TypographyH4 = ({ children, className, ...props }: HTMLAttributes & { children?: React.ReactNode }) => {
35 | return {children}
;
36 | };
37 |
38 | export const TypographyP = ({ children, className, ...props }: HTMLAttributes & { children?: React.ReactNode }) => {
39 | return {children}
;
40 | };
41 |
42 | export const TypographyBlockquote = ({ children, className, ...props }: HTMLAttributes & { children?: React.ReactNode }) => {
43 | return {children}
;
44 | };
45 |
46 | export const TypographyUL = ({ children, className, ...props }: HTMLAttributes & { children?: React.ReactNode }) => {
47 | return ;
48 | };
49 | export const TypographyOL = ({ children, className, ...props }: HTMLAttributes & { children?: React.ReactNode }) => {
50 | return {children}
;
51 | };
52 |
53 | export const TypographyInlineCode = ({ children, className, ...props }: HTMLAttributes & { children?: React.ReactNode }) => {
54 | return {children}
;
55 | };
56 |
57 | export const TypographyLead = ({ children, className, ...props }: HTMLAttributes & { children?: React.ReactNode }) => {
58 | return {children}
;
59 | };
60 |
61 | export const TypographySmall = ({ children, className, ...props }: HTMLAttributes & { children?: React.ReactNode }) => {
62 | return {children};
63 | };
64 |
--------------------------------------------------------------------------------
/components/ui/use-toast.ts:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | // Inspired by react-hot-toast library
4 | import * as React from "react"
5 |
6 | import type {
7 | ToastActionElement,
8 | ToastProps,
9 | } from "@/components/ui/toast"
10 |
11 | const TOAST_LIMIT = 1
12 | const TOAST_REMOVE_DELAY = 1000000
13 |
14 | type ToasterToast = ToastProps & {
15 | id: string
16 | title?: React.ReactNode
17 | description?: React.ReactNode
18 | action?: ToastActionElement
19 | }
20 |
21 | const actionTypes = {
22 | ADD_TOAST: "ADD_TOAST",
23 | UPDATE_TOAST: "UPDATE_TOAST",
24 | DISMISS_TOAST: "DISMISS_TOAST",
25 | REMOVE_TOAST: "REMOVE_TOAST",
26 | } as const
27 |
28 | let count = 0
29 |
30 | function genId() {
31 | count = (count + 1) % Number.MAX_SAFE_INTEGER
32 | return count.toString()
33 | }
34 |
35 | type ActionType = typeof actionTypes
36 |
37 | type Action =
38 | | {
39 | type: ActionType["ADD_TOAST"]
40 | toast: ToasterToast
41 | }
42 | | {
43 | type: ActionType["UPDATE_TOAST"]
44 | toast: Partial
45 | }
46 | | {
47 | type: ActionType["DISMISS_TOAST"]
48 | toastId?: ToasterToast["id"]
49 | }
50 | | {
51 | type: ActionType["REMOVE_TOAST"]
52 | toastId?: ToasterToast["id"]
53 | }
54 |
55 | interface State {
56 | toasts: ToasterToast[]
57 | }
58 |
59 | const toastTimeouts = new Map>()
60 |
61 | const addToRemoveQueue = (toastId: string) => {
62 | if (toastTimeouts.has(toastId)) {
63 | return
64 | }
65 |
66 | const timeout = setTimeout(() => {
67 | toastTimeouts.delete(toastId)
68 | dispatch({
69 | type: "REMOVE_TOAST",
70 | toastId: toastId,
71 | })
72 | }, TOAST_REMOVE_DELAY)
73 |
74 | toastTimeouts.set(toastId, timeout)
75 | }
76 |
77 | export const reducer = (state: State, action: Action): State => {
78 | switch (action.type) {
79 | case "ADD_TOAST":
80 | return {
81 | ...state,
82 | toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),
83 | }
84 |
85 | case "UPDATE_TOAST":
86 | return {
87 | ...state,
88 | toasts: state.toasts.map((t) =>
89 | t.id === action.toast.id ? { ...t, ...action.toast } : t
90 | ),
91 | }
92 |
93 | case "DISMISS_TOAST": {
94 | const { toastId } = action
95 |
96 | // ! Side effects ! - This could be extracted into a dismissToast() action,
97 | // but I'll keep it here for simplicity
98 | if (toastId) {
99 | addToRemoveQueue(toastId)
100 | } else {
101 | state.toasts.forEach((toast) => {
102 | addToRemoveQueue(toast.id)
103 | })
104 | }
105 |
106 | return {
107 | ...state,
108 | toasts: state.toasts.map((t) =>
109 | t.id === toastId || toastId === undefined
110 | ? {
111 | ...t,
112 | open: false,
113 | }
114 | : t
115 | ),
116 | }
117 | }
118 | case "REMOVE_TOAST":
119 | if (action.toastId === undefined) {
120 | return {
121 | ...state,
122 | toasts: [],
123 | }
124 | }
125 | return {
126 | ...state,
127 | toasts: state.toasts.filter((t) => t.id !== action.toastId),
128 | }
129 | }
130 | }
131 |
132 | const listeners: Array<(state: State) => void> = []
133 |
134 | let memoryState: State = { toasts: [] }
135 |
136 | function dispatch(action: Action) {
137 | memoryState = reducer(memoryState, action)
138 | listeners.forEach((listener) => {
139 | listener(memoryState)
140 | })
141 | }
142 |
143 | type Toast = Omit
144 |
145 | function toast({ ...props }: Toast) {
146 | const id = genId()
147 |
148 | const update = (props: ToasterToast) =>
149 | dispatch({
150 | type: "UPDATE_TOAST",
151 | toast: { ...props, id },
152 | })
153 | const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id })
154 |
155 | dispatch({
156 | type: "ADD_TOAST",
157 | toast: {
158 | ...props,
159 | id,
160 | open: true,
161 | onOpenChange: (open) => {
162 | if (!open) dismiss()
163 | },
164 | },
165 | })
166 |
167 | return {
168 | id: id,
169 | dismiss,
170 | update,
171 | }
172 | }
173 |
174 | function useToast() {
175 | const [state, setState] = React.useState(memoryState)
176 |
177 | React.useEffect(() => {
178 | listeners.push(setState)
179 | return () => {
180 | const index = listeners.indexOf(setState)
181 | if (index > -1) {
182 | listeners.splice(index, 1)
183 | }
184 | }
185 | }, [state])
186 |
187 | return {
188 | ...state,
189 | toast,
190 | dismiss: (toastId?: string) => dispatch({ type: "DISMISS_TOAST", toastId }),
191 | }
192 | }
193 |
194 | export { useToast, toast }
195 |
--------------------------------------------------------------------------------
/config.ts:
--------------------------------------------------------------------------------
1 |
2 | import { serpingApiConfig } from "serping/types";
3 |
4 | const regions = ["us-east-1"] as const;
5 | const locales = ['en', 'es', 'de', 'fr', 'it', 'nl', 'pl', 'pt', 'sv', 'tr', 'ru', 'zh', 'ja', "ko"] as const;
6 | const defaultLocale = "en" as const;
7 | const devices = ["desktop", "mobile"] as const;
8 |
9 |
10 | export type RegionType = typeof regions[number];
11 | export type LocaleType = typeof locales[number];
12 | export type DeviceType = typeof devices[number];
13 | export type SerpingApiType = Record
14 |
15 | const serpingApi: Record = {
16 | "us-east-1": {
17 | apiKey: process.env.SERPING_US_EAST_1_API_KEY!
18 | }
19 | }
20 | export const appConfig = {
21 | appDomain: "serpchecking.com",
22 | appName: "SERP Checking",
23 | appDescription: "SERP Checking",
24 | gaId: process.env.NEXT_PUBLIC_GA_ID,
25 | i18n: {
26 | locales,
27 | defaultLocale,
28 | labels: {
29 | "de": "Deutsch",
30 | "en": "English",
31 | "es": "Español",
32 | "fr": "Français",
33 | "it": "Italian",
34 | "pt": "Português",
35 | "nl": "Nederlands",
36 | "pl": "Polski",
37 | "sv": "Svenska",
38 | "tr": "Türkçe",
39 | "ru": "Русский",
40 | "ja": "日本語",
41 | "zh": "中文",
42 | "ko": "한국어"
43 | } as Record
44 | },
45 | regions,
46 | devices,
47 | serpingApi
48 | }
--------------------------------------------------------------------------------
/content/components/home/block1/de.md:
--------------------------------------------------------------------------------
1 | # SERP Checker
2 |
3 | Analysieren Sie SERPs aus über 200 Ländern und verschiedenen Sprachen
4 |
--------------------------------------------------------------------------------
/content/components/home/block1/en.md:
--------------------------------------------------------------------------------
1 | # SERP Checker
2 |
3 | Analyze SERPs from 200+ Countries & different languages
--------------------------------------------------------------------------------
/content/components/home/block1/es.md:
--------------------------------------------------------------------------------
1 | # SERP Gratuito
2 |
3 | Analiza SERPs de más de 200 países y diferentes idiomas
4 |
--------------------------------------------------------------------------------
/content/components/home/block1/fr.md:
--------------------------------------------------------------------------------
1 | # Vérificateur de SERP
2 |
3 | Analysez les SERP de plus de 200 pays et dans différentes langues
4 |
--------------------------------------------------------------------------------
/content/components/home/block1/it.md:
--------------------------------------------------------------------------------
1 | # Verificatore SERP
2 |
3 | Analizza i SERP da oltre 200 paesi e in diverse lingue
4 |
--------------------------------------------------------------------------------
/content/components/home/block1/ja.md:
--------------------------------------------------------------------------------
1 | # SERPチェッカー
2 |
3 | 200か国以上の国々と様々な言語のSERPを分析する
4 |
--------------------------------------------------------------------------------
/content/components/home/block1/ko.md:
--------------------------------------------------------------------------------
1 | # SERP 체커
2 |
3 | 200개 이상의 국가 및 다양한 언어로 SERP 분석
4 |
--------------------------------------------------------------------------------
/content/components/home/block1/nl.md:
--------------------------------------------------------------------------------
1 | # SERP Checker
2 |
3 | Analyseer SERP's uit meer dan 200 landen & verschillende talen
4 |
--------------------------------------------------------------------------------
/content/components/home/block1/pl.md:
--------------------------------------------------------------------------------
1 | # Sprawdzacz SERP
2 |
3 | Analizuj SERP z ponad 200 krajów i w różnych językach
4 |
--------------------------------------------------------------------------------
/content/components/home/block1/pt.md:
--------------------------------------------------------------------------------
1 | # Verificador de SERP
2 |
3 | Analise SERPs de mais de 200 países e em diferentes idiomas
4 |
--------------------------------------------------------------------------------
/content/components/home/block1/ru.md:
--------------------------------------------------------------------------------
1 | # SERP Checker
2 |
3 | Анализируйте SERP из более чем 200 стран и на разных языках
4 |
--------------------------------------------------------------------------------
/content/components/home/block1/sv.md:
--------------------------------------------------------------------------------
1 | # SERP-checker
2 |
3 | Analysera SERPs från över 200 länder & olika språk
4 |
--------------------------------------------------------------------------------
/content/components/home/block1/tr.md:
--------------------------------------------------------------------------------
1 | # SERP Denetleyicisi
2 |
3 | 200'den fazla ülkeden ve farklı dillerden SERP'leri analiz edin
4 |
--------------------------------------------------------------------------------
/content/components/home/block1/zh.md:
--------------------------------------------------------------------------------
1 | # SERP 检查器
2 |
3 | 分析来自200多个国家和不同语言的 SERP
4 |
--------------------------------------------------------------------------------
/content/components/home/block2/de.md:
--------------------------------------------------------------------------------
1 | ## Kostenloser SERP Checker: Globales Analysetool für Suchergebnisse
2 |
3 | Analysieren Sie SERPs aus über 230 Ländern mit SERP Checking
4 |
5 | SERP Checking bietet einen leistungsstarken, kostenlosen SERP Checker, der darauf ausgelegt ist, Ihnen umfassende Einblicke in die Suchergebnisseiten (SERPs) von Google für jedes Keyword zu geben. Unser Tool zeichnet sich durch unvergleichliche globale Abdeckung und detaillierte Analyse von SERP-Funktionen und Rich Results aus.
6 |
7 | ## Schlüsselfunktionen unseres kostenlosen SERP Checkers
8 |
9 | - **Globale SERP-Analyse**: Untersuchen Sie SERPs aus 243 Ländern.
10 | - **Mehrsprachige Unterstützung**: Wählen Sie aus zahlreichen Sprachen für präzise lokale SEO-Einblicke.
11 | - **Fokus auf Rich Results**: Erhalten Sie tiefe Einblicke in SERP-Funktionen wie Featured Snippets, People Also Ask und mehr.
12 | - **Umfassende Ergebnisse**: Analysieren Sie die Top 100 Suchergebnisse für eine vollständige Übersicht über die SERP-Landschaft.
13 | - **Gerätespezifische Analyse**: Wechseln Sie zwischen Desktop- und Mobilansichten für gezielte SEO-Strategien.
14 | - **SERP-Vorschau**: Visualisieren Sie tatsächliche Suchergebnisse, um das Potenzial der Klickrate (CTR) abzuschätzen.
15 |
16 | ## Wie Sie unseren kostenlosen SERP Checker nutzen
17 |
18 | 1. **Geben Sie Ihr Ziel-Keyword ein**: Geben Sie das zu analysierende Keyword in die Suchleiste ein.
19 | 2. **Wählen Sie Ihre Parameter**: Wählen Sie Ihr Ziel-Land, Sprache und Gerätetyp (Desktop/Mobil).
20 | 3. **Ergebnisse generieren**: Klicken Sie auf "Suchen", um die neuesten SERP-Daten abzurufen, einschließlich organischer Einträge und universeller Suchergebnisse.
21 |
22 | ## Umfassende SERP-Daten auf einen Blick
23 |
24 | Nach der Generierung der Ergebnisse erhalten Sie eine detaillierte Aufschlüsselung der Top 100 Suchergebnisse, einschließlich:
25 |
26 | - SERP-Position
27 | - Seitentitel
28 | - URL
29 | - SERP-Feature-Typ (falls zutreffend)
30 |
31 | ## Entdecken Sie Rich Results und SERP-Funktionen
32 |
33 | Der einzigartige Fokus unseres SERP Checkers auf Rich Results und SERP-Funktionen bietet wertvolle Einblicke in:
34 |
35 | - **People Also Ask-Boxen**: Entdecken Sie verwandte Fragen für die Ideenfindung und die Optimierung von Featured Snippets.
36 | - **Featured Snippets**: Identifizieren Sie "Position-Null"-Möglichkeiten, um die Sichtbarkeit Ihres Inhalts zu erhöhen.
37 | - **Wissenspaneele**: Verstehen Sie Googles priorisierte Informationsinhalte für auf Entitäten basierende Suchanfragen.
38 | - **Local Pack-Ergebnisse**: Wesentlich für Unternehmen, die geografisch spezifische Bereiche ansprechen und das lokale SEO verbessern wollen.
39 | - **Multimedia-Karussells**: Erkennen Sie Möglichkeiten für die Optimierung von Videos und Bildern in universellen Suchergebnissen.
40 |
41 | ## Visualisieren Sie Ihr SERP-Potenzial
42 |
43 | Nutzen Sie die Vorschaufunktion, um zu sehen, wie Ergebnisse in Google erscheinen und Ihnen helfen:
44 |
45 | - Die Volatilität der SERP in Ihrer Nische einschätzen
46 | - Potenzielle Klickraten für verschiedene Positionen abschätzen
47 | - Möglichkeiten zur Snippet-Optimierung identifizieren
48 |
49 | ## Warum sollten Sie den kostenlosen SERP Checker von SERP Checking wählen?
50 |
51 | Der kostenlose SERP Checker von SERP Checking ist ein unverzichtbares Werkzeug für SEO-Profis, Content-Ersteller und Unternehmen, die die Suchsichtbarkeit verbessern möchten. Durch die Bereitstellung einer umfassenden Übersicht über die globale SERP-Landschaft, einschließlich wichtiger Daten zu Rich Results und Einblicken in die Keyword-Schwierigkeit, ermöglicht unser Tool Ihnen, Konkurrenten in den Suchrankings zu übertreffen.
52 |
53 | Beginnen Sie heute damit, verborgene SERP-Chancen mit dem fortgeschrittenen, kostenlosen SERP Checker von SERP Checking aufzudecken!
54 |
--------------------------------------------------------------------------------
/content/components/home/block2/en.md:
--------------------------------------------------------------------------------
1 | ## Free SERP Checker: Global Search Results Analysis Tool
2 |
3 | Analyze SERPs from 230+ Countries with SERP Checking
4 |
5 | SERP Checking offers a powerful, free SERP checker designed to give you comprehensive insights into Google's search engine results pages (SERPs) for any keyword. Our tool stands out with unparalleled global coverage and detailed analysis of SERP features and Rich Results.
6 |
7 | ## Key Features of Our Free SERP Checker
8 |
9 | - **Global SERP Analysis**: Examine SERPs from 243 countries.
10 | - **Multilingual Support**: Select from numerous languages for precise local SEO insights.
11 | - **Rich Results Focus**: Gain deep insights into SERP features like Featured Snippets, People Also Ask, and more.
12 | - **Extensive Results**: Analyze the top 100 search results for a complete SERP landscape view.
13 | - **Device-Specific Analysis**: Toggle between desktop and mobile views for targeted SEO strategies.
14 | - **SERP Preview**: Visualize actual search results to estimate click-through rate (CTR) potential.
15 |
16 | ## How to Use Our Free SERP Checker
17 |
18 | 1. **Input Your Target Keyword**: Enter the keyword you want to analyze in the search bar.
19 | 2. **Select Your Parameters**: Choose your target country, language, and device type (desktop/mobile).
20 | 3. **Generate Results**: Click "Look Up" to retrieve the latest SERP data, including organic listings and universal search results.
21 |
22 | ## Comprehensive SERP Data at Your Fingertips
23 |
24 | After generating results, you'll receive a detailed breakdown of the top 100 search results, including:
25 |
26 | - SERP Position
27 | - Page Title
28 | - URL
29 | - SERP Feature Type (where applicable)
30 |
31 | ## Uncover Rich Results and SERP Features
32 |
33 | Our SERP checker's unique focus on Rich Results and SERP features provides valuable insights into:
34 |
35 | - **People Also Ask Boxes**: Discover related questions for content ideation and featured snippet optimization.
36 | - **Featured Snippets**: Identify "position zero" opportunities to enhance your content's visibility.
37 | - **Knowledge Panels**: Understand Google's prioritized informational content for entity-based searches.
38 | - **Local Pack Results**: Essential for businesses targeting specific geographic areas and improving local SEO.
39 | - **Multimedia Carousels**: Spot opportunities for video and image optimization in universal search results.
40 |
41 | ## Visualize Your SERP Potential
42 |
43 | Use the Preview feature to see how results appear in Google, helping you:
44 |
45 | - Assess SERP volatility in your niche
46 | - Estimate potential click-through rates for various positions
47 | - Identify snippet optimization opportunities
48 |
49 | ## Why Choose SERP Checking's Free SERP Checker?
50 |
51 | SERP Checking's free SERP checker is an essential tool for SEO professionals, content creators, and businesses aiming to improve search visibility. By offering a comprehensive view of the global SERP landscape, including crucial Rich Results data and keyword difficulty insights, our tool empowers you to outperform competitors in search rankings.
52 |
53 | Start uncovering hidden SERP opportunities today with SERP Checking's advanced, free SERP checker!
54 |
--------------------------------------------------------------------------------
/content/components/home/block2/es.md:
--------------------------------------------------------------------------------
1 | ## Comprobador SERP Gratuito: Herramienta de Análisis Global de Resultados de Búsqueda
2 |
3 | Analiza SERPs de más de 230 países con SERP Checking
4 |
5 | SERP Checking ofrece un potente comprobador SERP gratuito diseñado para brindarte insights completos sobre las páginas de resultados de motores de búsqueda (SERPs) de Google para cualquier palabra clave. Nuestra herramienta se destaca por su cobertura global incomparable y el análisis detallado de características de SERP y Resultados Enriquecidos.
6 |
7 | ## Características Clave de Nuestro Comprobador SERP Gratuito
8 |
9 | - **Análisis SERP Global**: Examina los SERP de 243 países.
10 | - **Soporte Multilingüe**: Selecciona entre numerosos idiomas para obtener información SEO local precisa.
11 | - **Enfoque en Resultados Enriquecidos**: Obtén información detallada sobre características de SERP como Fragmentos Destacados, People Also Ask y más.
12 | - **Resultados Extensos**: Analiza los 100 resultados de búsqueda principales para obtener una vista completa del paisaje de SERP.
13 | - **Análisis Específico por Dispositivo**: Alterna entre vistas de escritorio y móvil para estrategias SEO dirigidas.
14 | - **Vista Previa de SERP**: Visualiza resultados de búsqueda reales para estimar el potencial de tasa de clics (CTR).
15 |
16 | ## Cómo Usar Nuestro Comprobador SERP Gratuito
17 |
18 | 1. **Ingresa Tu Palabra Clave Objetivo**: Ingresa la palabra clave que deseas analizar en la barra de búsqueda.
19 | 2. **Selecciona Tus Parámetros**: Elige tu país objetivo, idioma y tipo de dispositivo (escritorio/móvil).
20 | 3. **Genera Resultados**: Haz clic en "Buscar" para obtener los últimos datos de SERP, incluidas las listas orgánicas y los resultados de búsqueda universales.
21 |
22 | ## Datos Completos de SERP a Tu Alcance
23 |
24 | Después de generar resultados, recibirás un desglose detallado de los 100 mejores resultados de búsqueda, incluyendo:
25 |
26 | - Posición en SERP
27 | - Título de la Página
28 | - URL
29 | - Tipo de Característica de SERP (si aplica)
30 |
31 | ## Descubre Resultados Enriquecidos y Características de SERP
32 |
33 | Nuestro comprobador SERP se enfoca en resultados enriquecidos y características de SERP para proporcionar valiosas ideas sobre:
34 |
35 | - **Casillas de People Also Ask**: Descubre preguntas relacionadas para la ideación de contenido y la optimización de fragmentos destacados.
36 | - **Fragmentos Destacados**: Identifica oportunidades de "posición cero" para mejorar la visibilidad de tu contenido.
37 | - **Paneles de Conocimiento**: Comprende el contenido informativo prioritario de Google para búsquedas basadas en entidades.
38 | - **Resultados de Pack Local**: Esenciales para negocios que apuntan a áreas geográficas específicas y para mejorar el SEO local.
39 | - **Carruseles Multimedia**: Identifica oportunidades para la optimización de video e imágenes en los resultados universales de búsqueda.
40 |
41 | ## Visualiza Tu Potencial en SERP
42 |
43 | Utiliza la función de Vista Previa para ver cómo aparecen los resultados en Google, lo que te ayuda a:
44 |
45 | - Evaluar la volatilidad del SERP en tu nicho
46 | - Estimar las tasas potenciales de clics para diferentes posiciones
47 | - Identificar oportunidades de optimización de fragmentos
48 |
49 | ## ¿Por Qué Elegir el Comprobador SERP Gratuito de SERP Checking?
50 |
51 | El comprobador SERP gratuito de SERP Checking es una herramienta esencial para profesionales SEO, creadores de contenido y negocios que desean mejorar su visibilidad en búsqueda. Ofrecemos una vista completa del paisaje global de SERP, incluidos datos cruciales sobre resultados enriquecidos y dificultad de palabras clave, lo que te permite superar a tus competidores en los rankings de búsqueda.
52 |
53 | ¡Comienza hoy mismo a descubrir oportunidades ocultas en SERP con el avanzado comprobador SERP gratuito de SERP Checking!
54 |
--------------------------------------------------------------------------------
/content/components/home/block2/fr.md:
--------------------------------------------------------------------------------
1 | ## SERP Checker gratuit : Outil d'analyse globale des résultats de recherche
2 |
3 | Analysez les SERP de plus de 230 pays avec SERP Checking
4 |
5 | SERP Checking offre un vérificateur de SERP gratuit et puissant conçu pour vous fournir des aperçus complets des pages de résultats de moteur de recherche (SERP) de Google pour tout mot-clé. Notre outil se distingue par une couverture globale inégalée et une analyse détaillée des fonctionnalités de SERP et des Rich Results.
6 |
7 | ## Caractéristiques principales de notre SERP Checker gratuit
8 |
9 | - **Analyse globale de SERP** : Examinez les SERP de 243 pays.
10 | - **Support multilingue** : Sélectionnez parmi de nombreuses langues pour des insights SEO locaux précis.
11 | - **Focus sur les Rich Results** : Obtenez des insights approfondis sur des fonctionnalités de SERP telles que les Featured Snippets, People Also Ask, et plus encore.
12 | - **Résultats étendus** : Analysez les 100 premiers résultats de recherche pour une vue complète du paysage SERP.
13 | - **Analyse spécifique aux appareils** : Alternez entre les vues bureau et mobile pour des stratégies SEO ciblées.
14 | - **Aperçu SERP** : Visualisez les résultats de recherche réels pour estimer le potentiel de taux de clic (CTR).
15 |
16 | ## Comment utiliser notre SERP Checker gratuit
17 |
18 | 1. **Entrez votre mot-clé cible** : Saisissez le mot-clé que vous souhaitez analyser dans la barre de recherche.
19 | 2. **Sélectionnez vos paramètres** : Choisissez votre pays cible, la langue et le type d'appareil (bureau/mobile).
20 | 3. **Générez les résultats** : Cliquez sur "Look Up" pour récupérer les dernières données SERP, y compris les listes organiques et les résultats de recherche universels.
21 |
22 | ## Données SERP complètes à portée de main
23 |
24 | Après la génération des résultats, vous recevrez une ventilation détaillée des 100 premiers résultats de recherche, incluant :
25 |
26 | - Position SERP
27 | - Titre de la page
28 | - URL
29 | - Type de fonctionnalité SERP (le cas échéant)
30 |
31 | ## Découvrez les Rich Results et les fonctionnalités SERP
32 |
33 | L'accent unique de notre vérificateur de SERP sur les Rich Results et les fonctionnalités SERP offre des insights précieux sur :
34 |
35 | - **Boîtes People Also Ask** : Découvrez des questions connexes pour l'idéation de contenu et l'optimisation des snippets en vedette.
36 | - **Featured Snippets** : Identifiez les opportunités de "position zéro" pour améliorer la visibilité de votre contenu.
37 | - **Panneaux de connaissances** : Comprenez le contenu informationnel priorisé de Google pour les recherches basées sur des entités.
38 | - **Résultats de pack local** : Essentiel pour les entreprises ciblant des zones géographiques spécifiques et améliorant le SEO local.
39 | - **Carrousels multimédia** : Repérez les opportunités d'optimisation vidéo et image dans les résultats de recherche universels.
40 |
41 | ## Visualisez votre potentiel SERP
42 |
43 | Utilisez la fonctionnalité d'aperçu pour voir comment les résultats apparaissent sur Google, vous aidant à :
44 |
45 | - Évaluer la volatilité du SERP dans votre niche
46 | - Estimer les taux de clic potentiels pour diverses positions
47 | - Identifier les opportunités d'optimisation de snippet
48 |
49 | ## Pourquoi choisir le SERP Checker gratuit de SERP Checking ?
50 |
51 | Le SERP checker gratuit de SERP Checking est un outil essentiel pour les professionnels du SEO, les créateurs de contenu et les entreprises visant à améliorer la visibilité de recherche. En offrant une vue complète du paysage SERP mondial, y compris des données cruciales sur les Rich Results et des insights sur la difficulté des mots-clés, notre outil vous permet de surpasser les concurrents dans les classements de recherche.
52 |
53 | Commencez dès aujourd'hui à découvrir des opportunités SERP cachées avec le SERP checker avancé et gratuit de SERP Checking !
54 |
--------------------------------------------------------------------------------
/content/components/home/block2/it.md:
--------------------------------------------------------------------------------
1 | ## SERP Checker Gratuito: Strumento di Analisi Globale dei Risultati di Ricerca
2 |
3 | Analizza i SERP da oltre 230 paesi con SERP Checking
4 |
5 | SERP Checking offre un potente SERP checker gratuito progettato per fornirti una visione completa delle pagine dei risultati dei motori di ricerca (SERP) di Google per qualsiasi parola chiave. Il nostro strumento si distingue per una copertura globale senza pari e un'analisi dettagliata delle caratteristiche dei SERP e dei Rich Results.
6 |
7 | ## Caratteristiche Principali del Nostro SERP Checker Gratuito
8 |
9 | - **Analisi Globale dei SERP**: Esamina i SERP da 243 paesi.
10 | - **Supporto Multilingue**: Scegli tra numerose lingue per insight SEO locali precisi.
11 | - **Focus sui Rich Results**: Ottieni approfondimenti sulle caratteristiche dei SERP come i Featured Snippets, People Also Ask, e altro ancora.
12 | - **Risultati Estesi**: Analizza i primi 100 risultati di ricerca per una visione completa del paesaggio dei SERP.
13 | - **Analisi Specifica per Dispositivo**: Alterna tra le visualizzazioni desktop e mobile per strategie SEO mirate.
14 | - **Anteprima SERP**: Visualizza i risultati di ricerca reali per stimare il potenziale tasso di clic (CTR).
15 |
16 | ## Come Utilizzare il Nostro SERP Checker Gratuito
17 |
18 | 1. **Inserisci la Tua Parola Chiave Target**: Inserisci la parola chiave che desideri analizzare nella barra di ricerca.
19 | 2. **Seleziona i Tuoi Parametri**: Scegli il tuo paese di destinazione, lingua e tipo di dispositivo (desktop/mobile).
20 | 3. **Genera Risultati**: Clicca su "Look Up" per recuperare gli ultimi dati SERP, inclusi gli elenchi organici e i risultati di ricerca universali.
21 |
22 | ## Dati SERP Completi a Portata di Mano
23 |
24 | Dopo aver generato i risultati, riceverai una ripartizione dettagliata dei primi 100 risultati di ricerca, inclusi:
25 |
26 | - Posizione SERP
27 | - Titolo della Pagina
28 | - URL
29 | - Tipo di Caratteristica SERP (ove applicabile)
30 |
31 | ## Scopri i Rich Results e le Caratteristiche dei SERP
32 |
33 | L'unico focus del nostro SERP checker sui Rich Results e sulle caratteristiche dei SERP fornisce preziosi insight su:
34 |
35 | - **Scatole di People Also Ask**: Scopri domande correlate per l'ideazione di contenuti e l'ottimizzazione dei snippet in primo piano.
36 | - **Featured Snippets**: Identifica le opportunità di "posizione zero" per migliorare la visibilità del tuo contenuto.
37 | - **Pannelli Informativi**: Comprendi il contenuto informativo prioritario di Google per le ricerche basate su entità.
38 | - **Risultati del Pacchetto Locale**: Essenziale per le aziende che mirano a specifiche aree geografiche e migliorano il SEO locale.
39 | - **Caroselli Multimediali**: Individua opportunità per l'ottimizzazione di video e immagini nei risultati di ricerca universali.
40 |
41 | ## Visualizza il Tuo Potenziale SERP
42 |
43 | Usa la funzione di anteprima per vedere come appaiono i risultati su Google, aiutandoti a:
44 |
45 | - Valutare la volatilità dei SERP nella tua nicchia
46 | - Stimare i potenziali tassi di clic per varie posizioni
47 | - Identificare le opportunità di ottimizzazione degli snippet
48 |
49 | ## Perché Scegliere il SERP Checker Gratuito di SERP Checking?
50 |
51 | Il SERP checker gratuito di SERP Checking è uno strumento essenziale per i professionisti SEO, i creatori di contenuti e le aziende che mirano a migliorare la visibilità di ricerca. Offrendo una visione completa del paesaggio globale dei SERP, inclusi dati cruciali sui Rich Results e insight sulla difficoltà delle parole chiave, il nostro strumento ti consente di superare i concorrenti nei ranking di ricerca.
52 |
53 | Inizia oggi a scoprire opportunità SERP nascoste con il SERP checker avanzato e gratuito di SERP Checking!
54 |
--------------------------------------------------------------------------------
/content/components/home/block2/ja.md:
--------------------------------------------------------------------------------
1 | ## 無料SERPチェッカー:グローバル検索結果分析ツール
2 |
3 | SERP Checkingで230カ国以上のSERPを分析
4 |
5 | SERP Checkingは、任意のキーワードに対するGoogleの検索エンジン結果ページ(SERP)について包括的な洞察を提供するために設計された強力な無料のSERPチェッカーを提供します。当社のツールは、比類のないグローバルカバレッジとSERP機能及びリッチリザルトの詳細な分析で際立っています。
6 |
7 | ## 無料SERPチェッカーの主な特徴
8 |
9 | - **グローバルSERP分析**:243カ国のSERPを調査します。
10 | - **多言語サポート**:正確なローカルSEOの洞察を得るために、多数の言語から選択します。
11 | - **リッチリザルトに焦点**:フィーチャードスニペット、People Also AskなどのSERP機能について深い洞察を得ます。
12 | - **広範囲な結果**:完全なSERPランドスケープビューのためにトップ100の検索結果を分析します。
13 | - **デバイス固有の分析**:ターゲットSEO戦略のためにデスクトップとモバイルビューを切り替えます。
14 | - **SERPプレビュー**:クリックスルーレート(CTR)の潜在的な見積もりをするために、実際の検索結果を視覚化します。
15 |
16 | ## 無料SERPチェッカーの使用方法
17 |
18 | 1. **ターゲットキーワードを入力**:分析したいキーワードを検索バーに入力します。
19 | 2. **パラメータを選択**:ターゲット国、言語、デバイスタイプ(デスクトップ/モバイル)を選択します。
20 | 3. **結果を生成**:"Look Up"をクリックして、オーガニックリスティングとユニバーサル検索結果を含む最新のSERPデータを取得します。
21 |
22 | ## 指先での包括的なSERPデータ
23 |
24 | 結果を生成した後、トップ100の検索結果の詳細な内訳を受け取ります。これには以下が含まれます:
25 |
26 | - SERP位置
27 | - ページタイトル
28 | - URL
29 | - 適用可能な場合のSERP機能タイプ
30 |
31 | ## リッチリザルトとSERP機能を発見
32 |
33 | 当社のSERPチェッカーのリッチリザルトとSERP機能に対するユニークな焦点は、以下について貴重な洞察を提供します:
34 |
35 | - **People Also Askボックス**:コンテンツのアイデア生成とフィーチャードスニペットの最適化のための関連する質問を発見します。
36 | - **フィーチャードスニペット**:"ゼロ位置"の機会を特定して、コンテンツの可視性を向上させます。
37 | - **ナレッジパネル**:エンティティベースの検索のためのGoogleの優先情報コンテンツを理解します。
38 | - **ローカルパック結果**:特定の地理的エリアをターゲットにしてローカルSEOを改善するビジネスにとって不可欠です。
39 | - **マルチメディアカルーセル**:ユニバーサル検索結果でのビデオおよび画像の最適化の機会を見つけます。
40 |
41 | ## SERPポテンシャルを視覚化
42 |
43 | プレビュー機能を使用して、Googleでの結果の表示方法を確認し、次のように支援します:
44 |
45 | - あなたのニッチでのSERPの変動性を評価
46 | - さまざまな位置での潜在的なクリックスルーレートを推定
47 | - スニペットの最適化の機会を特定
48 |
49 | ## なぜSERP Checkingの無料SERPチェッカーを選ぶのか?
50 |
51 | SERP Checkingの無料SERPチェッカーは、SEOの専門家、コンテンツクリエーター、検索の可視性を向上させることを目指すビジネスにとって不可欠なツールです。重要なリッチリザルトデータとキーワードの難易度の洞察を含む、グローバルなSERPランドスケープの包括的なビューを提供することで、当社のツールはあなたが検索ランキングで競合他社を上回ることを可能にします。
52 |
53 | 今日からSERP Checkingの高度な無料SERPチェッカーで隠れたSERPの機会を掘り起こし始めましょう!
54 |
--------------------------------------------------------------------------------
/content/components/home/block2/ko.md:
--------------------------------------------------------------------------------
1 | ## 무료 SERP Checker: 글로벌 검색 결과 분석 도구
2 |
3 | SERP Checking으로 230개 이상의 국가에서 SERP 분석
4 |
5 | SERP Checking은 어떤 키워드에 대한 Google의 검색 엔진 결과 페이지(SERP)에 대한 포괄적인 통찰력을 제공하도록 설계된 강력하고 무료인 SERP 체커를 제공합니다. 우리 도구는 비교할 수 없는 글로벌 커버리지와 SERP 기능 및 리치 결과의 자세한 분석으로 돋보입니다.
6 |
7 | ## 우리의 무료 SERP Checker의 주요 기능
8 |
9 | - **글로벌 SERP 분석**: 243개국의 SERP를 검토합니다.
10 | - **다국어 지원**: 정확한 로컬 SEO 인사이트를 위해 다수의 언어 중에서 선택하세요.
11 | - **리치 결과에 집중**: Featured Snippets, People Also Ask 등과 같은 SERP 기능에 대한 깊은 통찰을 얻습니다.
12 | - **광범위한 결과**: 완벽한 SERP 풍경을 보기 위해 상위 100개 검색 결과를 분석합니다.
13 | - **장치별 분석**: 타겟 SEO 전략을 위해 데스크탑 및 모바일 뷰 간 전환합니다.
14 | - **SERP 미리보기**: 클릭률(CTR) 잠재력을 추정하기 위해 실제 검색 결과를 시각화합니다.
15 |
16 | ## 우리의 무료 SERP Checker 사용 방법
17 |
18 | 1. **대상 키워드 입력**: 분석하려는 키워드를 검색 창에 입력합니다.
19 | 2. **매개변수 선택**: 대상 국가, 언어 및 기기 유형(데스크탑/모바일)을 선택합니다.
20 | 3. **결과 생성**: "Look Up"을 클릭하여 최신 SERP 데이터를 검색하고, 유기적 목록 및 범용 검색 결과를 포함합니다.
21 |
22 | ## 손끝에서 제공하는 포괄적인 SERP 데이터
23 |
24 | 결과를 생성한 후에는 다음을 포함하는 상위 100개 검색 결과의 자세한 분석을 받게 됩니다:
25 |
26 | - SERP 위치
27 | - 페이지 제목
28 | - URL
29 | - 해당하는 경우 SERP 기능 유형
30 |
31 | ## 리치 결과 및 SERP 기능 발견
32 |
33 | 우리의 SERP 체커의 리치 결과와 SERP 기능에 대한 독특한 초점은 다음에 대한 가치 있는 통찰을 제공합니다:
34 |
35 | - **People Also Ask 박스**: 컨텐츠 아이디어 생성 및 주요 스니펫 최적화를 위한 관련 질문을 발견하세요.
36 | - **주요 스니펫**: 컨텐츠의 가시성을 향상시킬 "0위치" 기회를 식별하세요.
37 | - **지식 패널**: 엔티티 기반 검색을 위한 Google의 우선순위 정보 콘텐츠를 이해합니다.
38 | - **로컬 팩 결과**: 특정 지리적 지역을 대상으로 하고 로컬 SEO를 개선하는 비즈니스에 필수적입니다.
39 | - **멀티미디어 캐러셀**: 범용 검색 결과에서 비디오 및 이미지 최적화 기회를 찾습니다.
40 |
41 | ## SERP 잠재력 시각화
42 |
43 | 미리보기 기능을 사용하여 Google에서 결과가 어떻게 표시되는지 확인하고, 다음을 도와줍니다:
44 |
45 | - 니치에서 SERP 변동성 평가
46 | - 다양한 위치에서 잠재적 클릭률 추정
47 | - 스니펫 최적화 기회 식별
48 |
49 | ## 왜 SERP Checking의 무료 SERP Checker를 선택해야 할까요?
50 |
51 | SERP Checking의 무료 SERP 체커는 검색 가시성을 개선하려는 SEO 전문가, 콘텐츠 크리에이터, 비즈니스를 위한 필수 도구입니다. 핵심 리치 결과 데이터 및 키워드 난이도 통찰을 포함한 글로벌 SERP 풍경의 포괄적인 전망을 제공함으로써, 우리 도구는 검색 순위에서 경쟁자들을 능가할 수 있게 합니다.
52 |
53 | 오늘 SERP Checking의 고급 무료 SERP 체커로 숨겨진 SERP 기회를 발견하기 시작하세요!
54 |
--------------------------------------------------------------------------------
/content/components/home/block2/nl.md:
--------------------------------------------------------------------------------
1 | ## Gratis SERP Checker: Wereldwijd Zoekresultaten Analyse Tool
2 |
3 | Analyseer SERP's uit meer dan 230 landen met SERP Checking
4 |
5 | SERP Checking biedt een krachtige, gratis SERP-checker die is ontworpen om u uitgebreide inzichten te geven in de zoekresultatenpagina's (SERP's) van Google voor elk trefwoord. Ons gereedschap onderscheidt zich met een ongeëvenaarde wereldwijde dekking en gedetailleerde analyse van SERP-functies en Rich Results.
6 |
7 | ## Belangrijkste kenmerken van onze gratis SERP Checker
8 |
9 | - **Wereldwijde SERP-analyse**: Onderzoek SERP's uit 243 landen.
10 | - **Meertalige ondersteuning**: Kies uit vele talen voor nauwkeurige lokale SEO-inzichten.
11 | - **Focus op Rich Results**: Verkrijg diepgaande inzichten in SERP-functies zoals Featured Snippets, People Also Ask, en meer.
12 | - **Uitgebreide resultaten**: Analyseer de top 100 zoekresultaten voor een volledig overzicht van het SERP-landschap.
13 | - **Apparaatspecifieke analyse**: Wissel tussen desktop- en mobiele weergaven voor gerichte SEO-strategieën.
14 | - **SERP Preview**: Visualiseer daadwerkelijke zoekresultaten om het potentieel van de klikfrequentie (CTR) te schatten.
15 |
16 | ## Hoe gebruik je onze gratis SERP Checker
17 |
18 | 1. **Voer je doelzoekwoord in**: Voer het zoekwoord dat je wilt analyseren in de zoekbalk in.
19 | 2. **Selecteer je parameters**: Kies je doelland, taal en apparaattype (desktop/mobiel).
20 | 3. **Genereer resultaten**: Klik op "Look Up" om de nieuwste SERP-gegevens op te halen, inclusief organische vermeldingen en universele zoekresultaten.
21 |
22 | ## Uitgebreide SERP-gegevens binnen handbereik
23 |
24 | Na het genereren van resultaten, ontvang je een gedetailleerde uitsplitsing van de top 100 zoekresultaten, inclusief:
25 |
26 | - SERP-positie
27 | - Paginatitel
28 | - URL
29 | - Type SERP-functie (indien van toepassing)
30 |
31 | ## Ontdek Rich Results en SERP-functies
32 |
33 | De unieke focus van onze SERP-checker op Rich Results en SERP-functies biedt waardevolle inzichten in:
34 |
35 | - **People Also Ask Boxes**: Ontdek gerelateerde vragen voor contentideeën en optimalisatie van uitgelichte snippets.
36 | - **Featured Snippets**: Identificeer "positie nul" kansen om de zichtbaarheid van je inhoud te verbeteren.
37 | - **Kennispanelen**: Begrijp de geprioriteerde informatieve inhoud van Google voor op entiteiten gebaseerde zoekopdrachten.
38 | - **Local Pack Results**: Essentieel voor bedrijven die specifieke geografische gebieden targeten en lokale SEO verbeteren.
39 | - **Multimedia Carrousels**: Spot kansen voor video- en beeldoptimalisatie in universele zoekresultaten.
40 |
41 | ## Visualiseer je SERP-potentieel
42 |
43 | Gebruik de previewfunctie om te zien hoe resultaten in Google verschijnen, wat je helpt om:
44 |
45 | - De volatiliteit van SERP in je niche te beoordelen
46 | - Potentiële klikfrequenties voor verschillende posities te schatten
47 | - Kansen voor snippet-optimalisatie te identificeren
48 |
49 | ## Waarom kiezen voor de gratis SERP Checker van SERP Checking?
50 |
51 | De gratis SERP-checker van SERP Checking is een essentieel hulpmiddel voor SEO-professionals, contentmakers en bedrijven die streven naar verbetering van zoekzichtbaarheid. Door een uitgebreid overzicht te bieden van het wereldwijde SERP-landschap, inclusief cruciale gegevens over Rich Results en inzichten in de moeilijkheidsgraad van zoekwoorden, stelt ons gereedschap je in staat om concurrenten in zoekrankings te overtreffen.
52 |
53 | Begin vandaag nog met het ontdekken van verborgen SERP-kansen met de geavanceerde, gratis SERP-checker van SERP Checking!
54 |
--------------------------------------------------------------------------------
/content/components/home/block2/pl.md:
--------------------------------------------------------------------------------
1 | ## Darmowy SERP Checker: Globalne Narzędzie do Analizy Wyników Wyszukiwania
2 |
3 | Analizuj SERP z ponad 230 krajów dzięki SERP Checking
4 |
5 | SERP Checking oferuje potężne, darmowe narzędzie do sprawdzania SERP, zaprojektowane, aby dostarczyć Ci kompleksowych informacji na temat stron wyników wyszukiwarki Google (SERP) dla dowolnego słowa kluczowego. Nasze narzędzie wyróżnia się niezrównanym globalnym zasięgiem i szczegółową analizą funkcji SERP oraz bogatych wyników.
6 |
7 | ## Kluczowe funkcje naszego darmowego SERP Checker
8 |
9 | - **Globalna analiza SERP**: Badaj SERP z 243 krajów.
10 | - **Wsparcie wielojęzyczne**: Wybierz z licznych języków, aby uzyskać precyzyjne lokalne spostrzeżenia SEO.
11 | - **Skupienie na bogatych wynikach**: Zyskaj głębokie spostrzeżenia na temat funkcji SERP, takich jak Featured Snippets, People Also Ask i inne.
12 | - **Obszerne wyniki**: Analizuj pierwsze 100 wyników wyszukiwania, aby uzyskać kompletny widok krajobrazu SERP.
13 | - **Analiza specyficzna dla urządzenia**: Przełączaj się między widokami na komputerze i urządzeniu mobilnym dla ukierunkowanych strategii SEO.
14 | - **Podgląd SERP**: Wizualizuj rzeczywiste wyniki wyszukiwania, aby oszacować potencjał współczynnika klikalności (CTR).
15 |
16 | ## Jak używać naszego darmowego SERP Checker
17 |
18 | 1. **Wprowadź swoje docelowe słowo kluczowe**: Wpisz słowo kluczowe, które chcesz przeanalizować, w pasku wyszukiwania.
19 | 2. **Wybierz swoje parametry**: Wybierz swój docelowy kraj, język i typ urządzenia (komputer/mobilny).
20 | 3. **Generuj wyniki**: Kliknij "Look Up", aby pobrać najnowsze dane SERP, w tym organiczne wpisy i wyniki wyszukiwania uniwersalnego.
21 |
22 | ## Kompleksowe dane SERP na wyciągnięcie ręki
23 |
24 | Po wygenerowaniu wyników otrzymasz szczegółowy podział pierwszych 100 wyników wyszukiwania, w tym:
25 |
26 | - Pozycja SERP
27 | - Tytuł strony
28 | - URL
29 | - Typ funkcji SERP (w razie potrzeby)
30 |
31 | ## Odkryj bogate wyniki i funkcje SERP
32 |
33 | Nasz SERP checker koncentruje się na bogatych wynikach i funkcjach SERP, dostarczając cennych spostrzeżeń na temat:
34 |
35 | - **Pudełka People Also Ask**: Odkryj powiązane pytania do tworzenia treści i optymalizacji fragmentów.
36 | - **Featured Snippets**: Zidentyfikuj możliwości „pozycji zero”, aby zwiększyć widoczność twojej treści.
37 | - **Panele wiedzy**: Zrozum priorytetową treść informacyjną Google dla wyszukiwań opartych na encjach.
38 | - **Wyniki lokalnego pakietu**: Niezbędne dla firm kierujących swoją ofertę do określonych obszarów geograficznych i poprawiających lokalne SEO.
39 | - **Karuzele multimedialne**: Znajdź możliwości optymalizacji wideo i obrazów w wynikach wyszukiwania uniwersalnego.
40 |
41 | ## Wizualizuj swój potencjał SERP
42 |
43 | Użyj funkcji podglądu, aby zobaczyć, jak wyniki pojawiają się w Google, pomagając ci:
44 |
45 | - Ocenić zmienność SERP w twojej niszy
46 | - Szacować potencjalne współczynniki klikalności dla różnych pozycji
47 | - Identyfikować możliwości optymalizacji snippetów
48 |
49 | ## Dlaczego wybrać darmowy SERP Checker od SERP Checking?
50 |
51 | Darmowy SERP checker od SERP Checking jest niezbędnym narzędziem dla profesjonalistów SEO, twórców treści i firm dążących do poprawy widoczności w wyszukiwarkach. Oferując kompleksowy widok na globalny krajobraz SERP, w tym kluczowe dane o bogatych wynikach i spostrzeżenia dotyczące trudności słów kluczowych, nasze narzędzie umożliwia ci przewyższenie konkurentów w rankingach wyszukiwania.
52 |
53 | Zacznij odkrywać ukryte możliwości SERP już dzisiaj za pomocą zaawansowanego, darmowego SERP checker od SERP Checking!
54 |
--------------------------------------------------------------------------------
/content/components/home/block2/pt.md:
--------------------------------------------------------------------------------
1 | ## SERP Checker Gratuito: Ferramenta de Análise Global de Resultados de Pesquisa
2 |
3 | Analise SERPs de mais de 230 países com SERP Checking
4 |
5 | O SERP Checking oferece um verificador de SERP gratuito e poderoso projetado para fornecer insights abrangentes sobre as páginas de resultados do motor de busca (SERPs) do Google para qualquer palavra-chave. Nosso instrumento destaca-se pela cobertura global incomparável e análise detalhada das funcionalidades dos SERP e Rich Results.
6 |
7 | ## Principais características do nosso SERP Checker Gratuito
8 |
9 | - **Análise Global de SERP**: Examine SERPs de 243 países.
10 | - **Suporte Multilíngue**: Escolha entre inúmeras línguas para insights precisos de SEO local.
11 | - **Foco em Rich Results**: Obtenha insights profundos sobre funcionalidades de SERP como Featured Snippets, People Also Ask e mais.
12 | - **Resultados Extensivos**: Analise os 100 principais resultados de pesquisa para uma visão completa da paisagem de SERP.
13 | - **Análise Específica para Dispositivos**: Alterne entre visualizações de desktop e mobile para estratégias de SEO direcionadas.
14 | - **Pré-visualização de SERP**: Visualize os resultados de pesquisa reais para estimar o potencial de taxa de cliques (CTR).
15 |
16 | ## Como Usar o Nosso SERP Checker Gratuito
17 |
18 | 1. **Insira Sua Palavra-chave Alvo**: Digite a palavra-chave que deseja analisar na barra de pesquisa.
19 | 2. **Selecione Seus Parâmetros**: Escolha seu país alvo, idioma e tipo de dispositivo (desktop/mobile).
20 | 3. **Gere Resultados**: Clique em "Look Up" para recuperar os dados mais recentes do SERP, incluindo listagens orgânicas e resultados de pesquisa universais.
21 |
22 | ## Dados Completos de SERP ao Seu Alcance
23 |
24 | Após gerar os resultados, você receberá uma análise detalhada dos 100 principais resultados de pesquisa, incluindo:
25 |
26 | - Posição no SERP
27 | - Título da Página
28 | - URL
29 | - Tipo de Funcionalidade do SERP (quando aplicável)
30 |
31 | ## Descubra Rich Results e Funcionalidades de SERP
32 |
33 | O foco único do nosso verificador de SERP em Rich Results e funcionalidades de SERP proporciona insights valiosos sobre:
34 |
35 | - **Caixas de People Also Ask**: Descubra perguntas relacionadas para ideias de conteúdo e otimização de snippets em destaque.
36 | - **Featured Snippets**: Identifique oportunidades de "posição zero" para melhorar a visibilidade do seu conteúdo.
37 | - **Painéis de Conhecimento**: Entenda o conteúdo informativo priorizado do Google para buscas baseadas em entidades.
38 | - **Resultados do Pacote Local**: Essencial para empresas que visam áreas geográficas específicas e melhoram o SEO local.
39 | - **Carrosséis Multimídia**: Identifique oportunidades para otimização de vídeos e imagens nos resultados de pesquisa universais.
40 |
41 | ## Visualize Seu Potencial de SERP
42 |
43 | Use o recurso de pré-visualização para ver como os resultados aparecem no Google, ajudando você:
44 |
45 | - Avaliar a volatilidade do SERP em seu nicho
46 | - Estimar taxas de cliques potenciais para várias posições
47 | - Identificar oportunidades de otimização de snippets
48 |
49 | ## Por Que Escolher o SERP Checker Gratuito da SERP Checking?
50 |
51 | O SERP checker gratuito da SERP Checking é uma ferramenta essencial para profissionais de SEO, criadores de conteúdo e empresas que visam melhorar a visibilidade nas pesquisas. Ao oferecer uma visão abrangente da paisagem global de SERP, incluindo dados cruciais de Rich Results e insights sobre dificuldades de palavras-chave, nossa ferramenta capacita você a superar os concorrentes nos rankings de pesquisa.
52 |
53 | Comece a descobrir oportunidades de SERP ocultas hoje com o avançado SERP checker gratuito da SERP Checking!
54 |
--------------------------------------------------------------------------------
/content/components/home/block2/ru.md:
--------------------------------------------------------------------------------
1 | ## Бесплатный SERP Checker: Глобальный инструмент анализа результатов поиска
2 |
3 | Анализируйте SERP из более чем 230 стран с помощью SERP Checking
4 |
5 | SERP Checking предлагает мощный бесплатный инструмент для проверки SERP, разработанный для предоставления всесторонних данных о страницах результатов поисковой системы Google (SERP) для любого ключевого слова. Наш инструмент выделяется непревзойденным глобальным охватом и детальным анализом функций SERP и Rich Results.
6 |
7 | ## Основные функции нашего бесплатного SERP Checker
8 |
9 | - **Глобальный анализ SERP**: Исследуйте SERP из 243 стран.
10 | - **Многоязычная поддержка**: Выберите из множества языков для точного анализа локального SEO.
11 | - **Фокус на Rich Results**: Получите глубокие знания о функциях SERP, таких как выделенные фрагменты, ответы на вопросы и многое другое.
12 | - **Обширные результаты**: Анализируйте первые 100 результатов поиска для полного представления о ландшафте SERP.
13 | - **Анализ специфичный для устройства**: Переключайтесь между представлениями для настольных и мобильных устройств для целевых стратегий SEO.
14 | - **Предварительный просмотр SERP**: Визуализируйте реальные результаты поиска, чтобы оценить потенциал кликабельности (CTR).
15 |
16 | ## Как использовать наш бесплатный SERP Checker
17 |
18 | 1. **Введите ваше целевое ключевое слово**: Введите ключевое слово для анализа в строку поиска.
19 | 2. **Выберите параметры**: Выберите целевую страну, язык и тип устройства (настольный/мобильный).
20 | 3. **Генерируйте результаты**: Нажмите "Look Up" для получения последних данных SERP, включая органические результаты и универсальные результаты поиска.
21 |
22 | ## Полные данные SERP у вас под рукой
23 |
24 | После генерации результатов вы получите подробное разбиение первых 100 результатов поиска, включая:
25 |
26 | - Позиция в SERP
27 | - Заголовок страницы
28 | - URL
29 | - Тип функции SERP (где применимо)
30 |
31 | ## Раскройте Rich Results и функции SERP
32 |
33 | Уникальный фокус нашего SERP checker на Rich Results и функциях SERP предоставляет ценные знания о:
34 |
35 | - **Коробки "Люди также спрашивают"**: Откройте для себя связанные вопросы для генерации контента и оптимизации выделенных фрагментов.
36 | - **Выделенные фрагменты**: Определите возможности "позиции ноль" для улучшения видимости вашего контента.
37 | - **Информационные панели**: Поймите, какую информационную содержание Google выделяет для поиска по сущностям.
38 | - **Локальные результаты**: Эссенциально для бизнесов, нацеленных на конкретные географические области и улучшение местного SEO.
39 | - **Мультимедийные карусели**: Найдите возможности для оптимизации видео и изображений в универсальных результатах поиска.
40 |
41 | ## Визуализируйте ваш потенциал в SERP
42 |
43 | Используйте функцию предварительного просмотра, чтобы увидеть, как результаты отображаются в Google, помогая вам:
44 |
45 | - Оценить волатильность SERP в вашей нише
46 | - Оценить потенциальные коэффициенты кликабельности для различных позиций
47 | - Определить возможности для оптимизации сниппетов
48 |
49 | ## Почему выбирают бесплатный SERP Checker от SERP Checking?
50 |
51 | Бесплатный SERP checker от SERP Checking — это необходимый инструмент для SEO-специалистов, создателей контента и бизнесов, стремящихся улучшить видимость в поиске. Предоставляя комплексное представление о глобальном ландшафте SERP, включая критически важные данные о Rich Results и сложности ключевых слов, наш инструмент позволяет вам превзойти конкурентов в рейтингах поиска.
52 |
53 | Начните раскрывать скрытые возможности SERP сегодня с продвинутым, бесплатным SERP checker от SERP Checking!
54 |
--------------------------------------------------------------------------------
/content/components/home/block2/sv.md:
--------------------------------------------------------------------------------
1 | ## Gratis SERP Checker: Globalt Verktyg för Analys av Sökmotorsresultat
2 |
3 | Analysera SERP från över 230 länder med SERP Checking
4 |
5 | SERP Checking erbjuder en kraftfull, gratis SERP-checker designad för att ge dig omfattande insikter i Googles sökmotorsresultatsidor (SERPs) för valfritt nyckelord. Vårt verktyg utmärker sig med oöverträffad global täckning och detaljerad analys av SERP-funktioner och Rich Results.
6 |
7 | ## Nyckelfunktioner i vår Gratis SERP Checker
8 |
9 | - **Global SERP-analys**: Undersök SERP från 243 länder.
10 | - **Flerspråkigt stöd**: Välj bland många språk för precisa lokala SEO-insikter.
11 | - **Fokus på Rich Results**: Få djupgående insikter i SERP-funktioner som Featured Snippets, People Also Ask och mer.
12 | - **Omfattande Resultat**: Analysera de topp 100 sökresultaten för en komplett vy över SERP-landskapet.
13 | - **Enhetsspecifik Analys**: Växla mellan desktop och mobilvyer för riktade SEO-strategier.
14 | - **SERP-förhandsgranskning**: Visualisera faktiska sökresultat för att uppskatta potentiell klickfrekvens (CTR).
15 |
16 | ## Hur man Använder Vår Gratis SERP Checker
17 |
18 | 1. **Mata in ditt mål-nyckelord**: Ange det nyckelord du vill analysera i sökfältet.
19 | 2. **Välj dina parametrar**: Välj ditt målland, språk och enhetstyp (desktop/mobil).
20 | 3. **Generera Resultat**: Klicka på "Look Up" för att hämta de senaste SERP-datan, inklusive organiska listningar och universella sökresultat.
21 |
22 | ## Omfattande SERP-data vid dina fingertoppar
23 |
24 | Efter att resultaten genererats får du en detaljerad uppdelning av de topp 100 sökresultaten, inklusive:
25 |
26 | - SERP-position
27 | - Sidtitel
28 | - URL
29 | - SERP-funktions typ (där tillämpligt)
30 |
31 | ## Upptäck Rich Results och SERP-funktioner
32 |
33 | Vårt SERP-checkers unika fokus på Rich Results och SERP-funktioner ger värdefulla insikter om:
34 |
35 | - **People Also Ask Boxar**: Upptäck relaterade frågor för innehållsidéer och optimering av framstående snippets.
36 | - **Featured Snippets**: Identifiera "position noll" möjligheter för att förbättra din innehålls synlighet.
37 | - **Kunskapspaneler**: Förstå Googles prioriterade informationsinnehåll för sökningar baserade på enheter.
38 | - **Lokala Paketresultat**: Väsentligt för företag som riktar sig mot specifika geografiska områden och förbättrar lokal SEO.
39 | - **Multimediekaruseller**: Identifiera möjligheter för video- och bildoptimering i universella sökresultat.
40 |
41 | ## Visualisera din SERP-potential
42 |
43 | Använd förhandsgranskningsfunktionen för att se hur resultaten visas i Google, vilket hjälper dig:
44 |
45 | - Bedöma SERP-volatilitet i din nisch
46 | - Uppskatta potentiella klickfrekvenser för olika positioner
47 | - Identifiera möjligheter för snippet-optimering
48 |
49 | ## Varför Välja SERP Checkings Gratis SERP Checker?
50 |
51 | SERP Checkings gratis SERP checker är ett avgörande verktyg för SEO-professionella, innehållsskapare och företag som siktar på att förbättra sökbarheten. Genom att erbjuda en omfattande vy över det globala SERP-landskapet, inklusive avgörande Rich Results-data och insikter om nyckelordsvårigheter, ger vårt verktyg dig möjligheten att överträffa konkurrenterna i sökrankningar.
52 |
53 | Börja upptäcka dolda SERP-möjligheter idag med SERP Checkings avancerade, gratis SERP checker!
54 |
--------------------------------------------------------------------------------
/content/components/home/block2/tr.md:
--------------------------------------------------------------------------------
1 | ## Ücretsiz SERP Checker: Küresel Arama Sonuçları Analiz Aracı
2 |
3 | SERP Checking ile 230+ Ülkeden SERP'leri Analiz Edin
4 |
5 | SERP Checking, herhangi bir anahtar kelime için Google'ın arama motoru sonuç sayfaları (SERPs) hakkında kapsamlı bilgiler sunmak üzere tasarlanmış güçlü, ücretsiz bir SERP kontrol cihazı sunar. Aracımız, eşsiz küresel kapsamı ve SERP özellikleri ile Zengin Sonuçların detaylı analizi ile öne çıkar.
6 |
7 | ## Ücretsiz SERP Checker'ımızın Temel Özellikleri
8 |
9 | - **Küresel SERP Analizi**: 243 ülkeden SERP'leri inceleyin.
10 | - **Çok Dilli Destek**: Kesin yerel SEO içgörüleri için birçok dilden seçim yapın.
11 | - **Zengin Sonuçlara Odaklanma**: Öne Çıkan Snippet'lar, People Also Ask gibi SERP özellikleri hakkında derinlemesine bilgi edinin.
12 | - **Kapsamlı Sonuçlar**: Tam bir SERP manzarası görünümü için ilk 100 arama sonucunu analiz edin.
13 | - **Cihaza Özel Analiz**: Hedeflenmiş SEO stratejileri için masaüstü ve mobil görünümler arasında geçiş yapın.
14 | - **SERP Önizlemesi**: Tıklama oranı (CTR) potansiyelini tahmin etmek için gerçek arama sonuçlarını görselleştirin.
15 |
16 | ## Ücretsiz SERP Checker'ımızı Nasıl Kullanırsınız
17 |
18 | 1. **Hedef Anahtar Kelimenizi Girin**: Analiz etmek istediğiniz anahtar kelimeyi arama çubuğuna girin.
19 | 2. **Parametrelerinizi Seçin**: Hedef ülkenizi, dilinizi ve cihaz türünüzü (masaüstü/mobil) seçin.
20 | 3. **Sonuçları Üretin**: En son SERP verilerini, organik listeler ve evrensel arama sonuçları dahil olmak üzere almak için "Look Up" düğmesine tıklayın.
21 |
22 | ## Parmağınızın Ucunda Kapsamlı SERP Verileri
23 |
24 | Sonuçları ürettikten sonra, şunları içeren ilk 100 arama sonucunun detaylı bir ayrıntısını alacaksınız:
25 |
26 | - SERP Pozisyonu
27 | - Sayfa Başlığı
28 | - URL
29 | - Uygulanan yerde SERP Özellik Türü
30 |
31 | ## Zengin Sonuçları ve SERP Özelliklerini Keşfedin
32 |
33 | SERP checker'ımızın Zengin Sonuçlar ve SERP özelliklerine özgü odaklanması, şu konularda değerli içgörüler sağlar:
34 |
35 | - **People Also Ask Kutuları**: İçerik fikirleri oluşturma ve öne çıkan snippet optimizasyonu için ilgili soruları keşfedin.
36 | - **Öne Çıkan Snippet'lar**: İçeriğinizin görünürlüğünü artırmak için "sıfır pozisyonu" fırsatlarını belirleyin.
37 | - **Bilgi Panelleri**: Google'ın varlık tabanlı aramalar için öncelikli bilgi içeriğini anlayın.
38 | - **Yerel Paket Sonuçları**: Belirli coğrafi alanları hedefleyen işletmeler ve yerel SEO'yu iyileştirmek için esastır.
39 | - **Multimedya Karuselleri**: Evrensel arama sonuçlarında video ve görüntü optimizasyonu fırsatlarını belirleyin.
40 |
41 | ## SERP Potansiyelinizi Görselleştirin
42 |
43 | Önizleme özelliğini kullanarak, sonuçların Google'da nasıl göründüğünü görün, bu da size şu konularda yardımcı olur:
44 |
45 | - Nişinizdeki SERP volatilitesini değerlendirin
46 | - Çeşitli pozisyonlar için potansiyel tıklama oranlarını tahmin edin
47 | - Snippet optimizasyon fırsatlarını belirleyin
48 |
49 | ## Neden SERP Checking'in Ücretsiz SERP Checker'ını Seçmelisiniz?
50 |
51 | SERP Checking'in ücretsiz SERP checker'ı, arama görünürlüğünü iyileştirmeyi amaçlayan SEO profesyonelleri, içerik üreticileri ve işletmeler için temel bir araçtır. Küresel SERP manzarasının kapsamlı bir görünümünü sunarak, kritik Zengin Sonuç verileri ve anahtar kelime zorluk içgörüleri dahil, aracımız sizi arama sıralamalarında rakiplerinizi geçmeye yetkilendirir.
52 |
53 | SERP Checking'in gelişmiş, ücretsiz SERP checker'ı ile bugün gizli SERP fırsatlarını keşfetmeye başlayın!
54 |
--------------------------------------------------------------------------------
/content/components/home/block2/zh.md:
--------------------------------------------------------------------------------
1 | ## 免费SERP检查器:全球搜索结果分析工具
2 |
3 | 使用SERP Checking分析来自230多个国家的SERP
4 |
5 | SERP Checking提供了一个强大的免费SERP检查器,旨在为您提供Google搜索引擎结果页面(SERP)的全面洞察,适用于任何关键词。我们的工具以无与伦比的全球覆盖和对SERP功能及丰富结果的详细分析而脱颖而出。
6 |
7 | ## 我们免费SERP检查器的关键特性
8 |
9 | - **全球SERP分析**:检查来自243个国家的SERP。
10 | - **多语言支持**:选择众多语言,获得精准的本地SEO洞察。
11 | - **丰富结果聚焦**:深入了解SERP功能,如特色摘要、用户还询问等。
12 | - **广泛结果**:分析前100个搜索结果,以获得完整的SERP景观视图。
13 | - **设备特定分析**:在桌面和移动视图之间切换,针对性地制定SEO策略。
14 | - **SERP预览**:可视化实际搜索结果,估算点击通过率(CTR)潜力。
15 |
16 | ## 如何使用我们的免费SERP检查器
17 |
18 | 1. **输入您的目标关键词**:在搜索栏中输入您要分析的关键词。
19 | 2. **选择您的参数**:选择目标国家、语言和设备类型(桌面/移动)。
20 | 3. **生成结果**:点击“查找”检索最新的SERP数据,包括有机列表和通用搜索结果。
21 |
22 | ## 您指尖下的全面SERP数据
23 |
24 | 生成结果后,您将收到前100个搜索结果的详细分解,包括:
25 |
26 | - SERP位置
27 | - 页面标题
28 | - URL
29 | - SERP特征类型(适用时)
30 |
31 | ## 揭示丰富结果和SERP特征
32 |
33 | 我们SERP检查器独特的丰富结果和SERP特征聚焦提供了宝贵的洞察:
34 |
35 | - **用户还询问盒子**:发现相关问题以进行内容创意和特色摘要优化。
36 | - **特色摘要**:识别“零位置”机会以增强您的内容可见性。
37 | - **知识面板**:了解Google对基于实体搜索的优先信息内容。
38 | - **本地包结果**:对瞄准特定地理区域并改善本地SEO的企业至关重要。
39 | - **多媒体轮播**:在通用搜索结果中发现视频和图像优化的机会。
40 |
41 | ## 可视化您的SERP潜力
42 |
43 | 使用预览功能查看结果在Google中的显示方式,帮助您:
44 |
45 | - 评估您细分市场中的SERP波动
46 | - 估算各个位置的潜在点击率
47 | - 识别摘要优化机会
48 |
49 | ## 为什么选择SERP Checking的免费SERP检查器?
50 |
51 | SERP Checking的免费SERP检查器是SEO专业人士、内容创作者和旨在提高搜索可见性的企业的必备工具。通过提供全球SERP景观的全面视图,包括关键的丰富结果数据和关键词难度洞察,我们的工具赋予您超越竞争对手的能力。
52 |
53 | 立即开始使用SERP Checking的高级免费SERP检查器,发掘隐藏的SERP机会!
54 |
--------------------------------------------------------------------------------
/data/generated/components-markdown.json:
--------------------------------------------------------------------------------
1 | {
2 | "home/block1": {
3 | "locales": [
4 | "de",
5 | "en",
6 | "es",
7 | "fr",
8 | "it",
9 | "ja",
10 | "ko",
11 | "nl",
12 | "pl",
13 | "pt",
14 | "ru",
15 | "sv",
16 | "tr",
17 | "zh"
18 | ]
19 | },
20 | "home/block2": {
21 | "locales": [
22 | "de",
23 | "en",
24 | "es",
25 | "fr",
26 | "it",
27 | "ja",
28 | "ko",
29 | "nl",
30 | "pl",
31 | "pt",
32 | "ru",
33 | "sv",
34 | "tr",
35 | "zh"
36 | ]
37 | }
38 | }
--------------------------------------------------------------------------------
/i18n.ts:
--------------------------------------------------------------------------------
1 | import deepmerge from "deepmerge";
2 | import fs from "fs";
3 | import type { AbstractIntlMessages } from "next-intl";
4 | import { getRequestConfig } from "next-intl/server";
5 | import path from "path";
6 | import z from "zod";
7 | import { LocaleType, appConfig } from "./config";
8 |
9 | export const getLocale = (
10 | locale: string,
11 | ): AbstractIntlMessages => {
12 | const data = fs.readFileSync(path.join(process.cwd(), `./locales/${locale}.json`), 'utf-8');
13 | return JSON.parse(data) as AbstractIntlMessages;
14 | };
15 |
16 | export const getMessagesForLocale = (
17 | locale: string,
18 | ): AbstractIntlMessages => {
19 | const localeMessages = getLocale(locale);
20 | if (locale === appConfig.i18n.defaultLocale) {
21 | return localeMessages;
22 | }
23 | const defaultLocaleMessages = getLocale(
24 | appConfig.i18n.defaultLocale,
25 | );
26 | return deepmerge(defaultLocaleMessages, localeMessages);
27 | };
28 |
29 | export default getRequestConfig(({ locale }) => ({
30 | messages: getMessagesForLocale(locale),
31 | }));
32 |
33 | // I18n Components Markdown
34 | export const componentsMarkdownFile = "data/generated/components-markdown.json";
35 | export const contentComponentsMarkdownDir = 'content/components';
36 |
37 | export const I18nComponentMarkdownSchema = z.record(
38 | z.object({
39 | locales: z.array(z.enum(appConfig.i18n.locales))
40 | })
41 | );
42 | export type I18nComponentMarkdown = z.infer;
43 | let loadComponentsMarkdownData;
44 | if (!loadComponentsMarkdownData) {
45 | try {
46 | const file = fs.readFileSync(path.join(process.cwd(), componentsMarkdownFile), 'utf-8');
47 | if (file) loadComponentsMarkdownData = I18nComponentMarkdownSchema.parse(JSON.parse(file));
48 | // console.log("Components markdown data is valid.");
49 | } catch (validationError: any) {
50 | console.error("Validation error:", validationError.errors);
51 | }
52 | }
53 | export const componentsMarkdownData: I18nComponentMarkdown | null = loadComponentsMarkdownData ? loadComponentsMarkdownData : null;
54 |
55 | export const getComponentMarkdown = ({
56 | locale,
57 | componentPathName
58 | }: {
59 | locale: LocaleType;
60 | componentPathName: string;
61 | }): string | undefined => {
62 | if (!componentsMarkdownData) return undefined;
63 |
64 | // load locales by componentPathName
65 | const { locales } = componentsMarkdownData[componentPathName] as { locales: LocaleType[] };
66 | const currentLocale = locales.includes(locale) ? locale : appConfig.i18n.defaultLocale;
67 | const filePath = path.join(process.cwd(), contentComponentsMarkdownDir, componentPathName, `${currentLocale}.md`);
68 | try {
69 | return fs.readFileSync(filePath, 'utf-8');
70 | } catch (error) {
71 | console.error(`Error reading Markdown file: ${error}`);
72 | return undefined;
73 | }
74 | };
--------------------------------------------------------------------------------
/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/serping/serp-checker/27c23062dbdadfdf56210c7a7929f47079b2dfbf/image.png
--------------------------------------------------------------------------------
/lib/api.ts:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 | import { toast } from "react-hot-toast";
3 |
4 | const apiClient = axios.create({
5 | baseURL: "/api",
6 | });
7 |
8 | apiClient.interceptors.response.use(
9 | function (response) {
10 | return response.data;
11 | },
12 |
13 | function (error) {
14 | let message = "";
15 |
16 | if (error.response?.status === 403) {
17 | message = "Unauthorized";
18 | } else if (error.response?.status === 402) {
19 | message = "Pick a plan to use this feature";
20 | } else {
21 | message =
22 | error?.response?.data?.error || error.message || error.toString();
23 | }
24 |
25 | error.message =
26 | typeof message === "string" ? message : JSON.stringify(message);
27 |
28 | console.error(error.message);
29 |
30 | if (error.message) {
31 | toast.error(error.message);
32 | } else {
33 | toast.error("something wrong...");
34 | }
35 | return Promise.reject(error);
36 | }
37 | );
38 |
39 | export default apiClient;
40 |
--------------------------------------------------------------------------------
/lib/i18n.ts:
--------------------------------------------------------------------------------
1 | import { appConfig } from "@/config";
2 | import { createSharedPathnamesNavigation } from "next-intl/navigation";
3 |
4 | export const { Link, redirect, usePathname, useRouter } = createSharedPathnamesNavigation({
5 | locales: appConfig.i18n.locales,
6 | localePrefix: "never"
7 | });
8 |
--------------------------------------------------------------------------------
/lib/utils.ts:
--------------------------------------------------------------------------------
1 | import { appConfig, LocaleType } from "@/config";
2 | import { type ClassValue, clsx } from "clsx";
3 | import { twMerge } from "tailwind-merge";
4 |
5 | export function cn(...inputs: ClassValue[]) {
6 | return twMerge(clsx(inputs))
7 | }
8 |
9 | export const getOrigin = ({ headers }: { headers: Headers }) => {
10 | const host = headers.get('host') || appConfig.appDomain;
11 |
12 | const protocol = ['localhost', '127.0.0.1'].includes(host.split(":")[0]) ? 'http' : 'https';
13 | return `${protocol}://${host}`;
14 | }
15 |
16 | export const getCanonical = ({ headers }: { headers: Headers }) => {
17 | const origin = getOrigin({ headers });
18 | const url = new URL(headers.get("x-request-url")!);
19 | return `${origin}${url.pathname}`;
20 | }
21 |
22 | export const createAlternates = ({ headers }: { headers: Headers; }) => {
23 | const languages = {} as Record;
24 | const linkStr = headers.get("Link")!;
25 | const links = linkStr.split(',');
26 | links.forEach(alternateStr => {
27 | const match = alternateStr.match(/<(.*)>;.*hreflang="(.*)"/);
28 | if (match && match[1]) {
29 | if (match[2] !== "x-default") {
30 | languages[match[2] as LocaleType] = match[1];
31 | } else {
32 | languages[appConfig.i18n.defaultLocale] = match[1];
33 | }
34 | }
35 | })
36 |
37 | return {
38 | canonical: getCanonical({ headers }),
39 | languages
40 | }
41 | }
--------------------------------------------------------------------------------
/locales/de.json:
--------------------------------------------------------------------------------
1 | {
2 | "frontend": {
3 | "home": {
4 | "faq": {
5 | "qa1": {
6 | "answer": "Um das Ranking Ihrer Website in den SERP zu verbessern, können Sie die folgenden Methoden verwenden:\n\n- **Suchmaschinenoptimierung (SEO)**:\nOptimieren Sie den Inhalt, die Struktur und den Code Ihrer Website, um das Ranking in den organischen Suchergebnissen zu verbessern.\n\n- **Keyword-Recherche**:\nWählen und verwenden Sie Keywords mit hohem Traffic, die für Ihr Geschäft relevant sind.\n\n- **Hochwertige Inhalte**:\nErstellen Sie wertvolle, originale und relevante Inhalte, die den Suchbedürfnissen der Nutzer entsprechen.\n\n- **Optimierung der Website-Performance**:\nVerbessern Sie die Ladegeschwindigkeit Ihrer Website und deren mobile Kompatibilität.\n\n- **Erwerb qualitativ hochwertiger Backlinks**:\nErhalten Sie Links von anderen autoritativen Websites, um die Autorität Ihrer Website zu erhöhen.\n",
7 | "question": "Wie kann ich das Ranking meiner Website in den SERP verbessern?"
8 | }
9 | }
10 | },
11 | "serp": {
12 | "images": "Bilder",
13 | "videos": "Videos",
14 | "places": "Setzt",
15 | "related_searches": "Verwandte Suchanfragen",
16 | "download_csv": "CSV herunterladen"
17 | },
18 | "snapshot": "Schnappschuss"
19 | },
20 | "home": {
21 | "status": {
22 | "online_google": "Online-Google"
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/locales/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "menu": {
3 | "serp_checker": "Serp Checker",
4 | "light": "Light",
5 | "dark": "Dark",
6 | "system": "System"
7 | },
8 | "frontend": {
9 | "go_to_homepage": "Go to homepage",
10 | "page_not_found": "Page not found",
11 | "home": {
12 | "position": "Position",
13 | "type": "Serp Type",
14 | "title": "Title",
15 | "results_for": "Results for \"{query}\"",
16 | "views": {
17 | "preview": "Preview"
18 | },
19 | "look_up": "Look Up",
20 | "form": {
21 | "query": {
22 | "error": {
23 | "message": "Query must be at least 2 characters."
24 | }
25 | }
26 | },
27 | "faq": {
28 | "title": "Faqs",
29 | "qa1": {
30 | "question": "How can I improve my website's ranking on the SERP?",
31 | "answer": "To improve your website's ranking on the SERP, you can use the following methods:\n\n- **Search Engine Optimization (SEO)**:\nOptimize your website's content, structure, and code to enhance its ranking in organic search results.\n\n- **Keyword Research**:\nChoose and use high-traffic keywords relevant to your business.\n\n- **High-Quality Content**:\nCreate valuable, original, and relevant content that meets users' search needs.\n\n- **Website Performance Optimization**:\nImprove your website's loading speed and mobile compatibility.\n\n- **Acquire Quality Backlinks**:\nObtain links from other authoritative websites to increase your site's authority.\n"
32 | },
33 | "qa2": {
34 | "question": "What are Google SERP Features?",
35 | "answer": "Google SERP features are special results that appear on the search engine results page, such as Rich Results. These include:\n\n- Featured Snippets\n- People Also Ask boxes\n- Knowledge Panels\n- Local Pack results\n- Video and Image Carousels\n"
36 | },
37 | "qa3": {
38 | "question": "Why Use a SERP Checker Tool?",
39 | "answer": "A SERP checker tool helps you:\n\n- Track your website's ranking\n- Analyze SERPs from different countries and regions\n- View SERPs in various languages\n- Monitor the presence of Rich Results\n- View SERPs from any location\n"
40 | },
41 | "qa4": {
42 | "answer": "Yes, our SERP checker is free. In the future, there may be some usage limits.",
43 | "question": "Is the SERP Checker Free Forever?"
44 | },
45 | "qa5": {
46 | "question": "Do You Provide a SERP Checker API?",
47 | "answer": "Yes, I have developed a SERP API and offer it through [SERP.ING](https://www.serp.ing). It is the most cost-effective SERP API in the industry, including all major Rich Results."
48 | }
49 | }
50 | },
51 | "serp": {
52 | "featured_snippets": "Featured Snippets",
53 | "people_also_ask": "People Also Ask",
54 | "things_to_know": "Things To Know",
55 | "x": "X",
56 | "twitter": {
57 | "post": {
58 | "posted_on": "Posted On"
59 | }
60 | },
61 | "top_stories": {
62 | "title": "Top Stories"
63 | },
64 | "images": "Images",
65 | "videos": "Videos",
66 | "places": "Places",
67 | "related_searches": "Related Searches",
68 | "download_csv": "Download CSV",
69 | "url": "URL filtering",
70 | "recipes": "Recipes"
71 | },
72 | "meta": {
73 | "default": {
74 | "title": "SERP Checking - Free SERP Checker for Fast, Accurate Google Rank & Rich Results",
75 | "description": "Use our free SERP checker to analyze results from 230+ countries. Get insights on Rich Results, top 100 rankings, and more. Boost your SEO with SERP Checking now!"
76 | }
77 | },
78 | "desktop": "Desktop",
79 | "snapshot": "Snapshot"
80 | },
81 | "home": {
82 | "status": {
83 | "online_google": "Online Google"
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/locales/es.json:
--------------------------------------------------------------------------------
1 | {
2 | "menu": {
3 | "serp_checker": "Verificador de SERP",
4 | "light": "Claro",
5 | "dark": "Oscuro",
6 | "system": "Sistema"
7 | },
8 | "frontend": {
9 | "go_to_homepage": "Ir a la página de inicio",
10 | "page_not_found": "Página no encontrada",
11 | "home": {
12 | "position": "Posición",
13 | "type": "Tipo de SERP",
14 | "title": "Título",
15 | "results_for": "Resultados para \"{query}\"",
16 | "views": {
17 | "preview": "Vista previa"
18 | },
19 | "look_up": "Buscar",
20 | "form": {
21 | "query": {
22 | "error": {
23 | "message": "La consulta debe tener al menos 2 caracteres."
24 | }
25 | }
26 | },
27 | "faq": {
28 | "title": "Preguntas frecuentes",
29 | "qa1": {
30 | "question": "¿Cómo puedo mejorar la clasificación de mi sitio web en el SERP?",
31 | "answer": "Para mejorar el ranking de tu sitio web en los SERP, puedes usar los siguientes métodos:\n\n- **Optimización para motores de búsqueda (SEO)**:\nOptimiza el contenido, la estructura y el código de tu sitio web para mejorar su posición en los resultados de búsqueda orgánica.\n\n- **Investigación de palabras clave**:\nElige y usa palabras clave con alto tráfico relevantes para tu negocio.\n\n- **Contenido de alta calidad**:\nCrea contenido valioso, original y relevante que satisfaga las necesidades de búsqueda de los usuarios.\n\n- **Optimización del rendimiento del sitio web**:\nMejora la velocidad de carga de tu sitio web y su compatibilidad móvil.\n\n- **Adquirir backlinks de calidad**:\nObtén enlaces de otros sitios web autorizados para aumentar la autoridad de tu sitio.\n"
32 | },
33 | "qa2": {
34 | "question": "¿Qué son las características de SERP de Google?",
35 | "answer": "Las características de SERP de Google son resultados especiales que aparecen en la página de resultados del motor de búsqueda, como los resultados enriquecidos. Estos incluyen:\n\n- Fragmentos destacados\n- Cajas de 'La gente también pregunta'\n- Paneles de conocimiento\n- Resultados del paquete local\n- Carruseles de videos e imágenes\n"
36 | },
37 | "qa3": {
38 | "question": "¿Por qué usar una herramienta de verificación de SERP?",
39 | "answer": "Una herramienta de verificación de SERP le ayuda a:\n\n- Rastrear la clasificación de su sitio web\n- Analizar SERP de diferentes países y regiones\n- Ver SERP en varios idiomas\n- Monitorear la presencia de resultados enriquecidos\n- Ver SERP desde cualquier ubicación\n"
40 | },
41 | "qa4": {
42 | "answer": "Sí, nuestro verificador de SERP es gratuito. En el futuro, puede haber algunos límites de uso.",
43 | "question": "¿El verificador de SERP es gratuito para siempre?"
44 | },
45 | "qa5": {
46 | "question": "¿Proporcionan una API de verificación de SERP?",
47 | "answer": "Sí, he desarrollado una API de SERP y la ofrezco a través de [SERP.ING](https://www.serp.ing). Es la API de SERP más rentable de la industria, incluyendo todos los resultados enriquecidos principales."
48 | }
49 | }
50 | },
51 | "serp": {
52 | "featured_snippets": "Fragmentos destacados",
53 | "people_also_ask": "La gente también pregunta",
54 | "things_to_know": "Cosas que saber",
55 | "x": "X",
56 | "twitter": {
57 | "post": {
58 | "posted_on": "Publicado en"
59 | }
60 | },
61 | "top_stories": {
62 | "title": "Principales noticias"
63 | },
64 | "images": "Imágenes",
65 | "videos": "Vídeos",
66 | "places": "Lugares",
67 | "related_searches": "búsquedas relacionadas",
68 | "download_csv": "Descargar CSV"
69 | },
70 | "meta": {
71 | "default": {
72 | "title": "Verificación de SERP - Verificador de SERP gratuito para resultados precisos y rápidos de Google Rank y resultados enriquecidos",
73 | "description": "Use nuestro verificador de SERP gratuito para analizar resultados de más de 230 países. Obtenga información sobre resultados enriquecidos, los 100 mejores rankings y más. ¡Mejore su SEO con la verificación de SERP ahora!"
74 | }
75 | },
76 | "desktop": "Escritorio",
77 | "snapshot": "Instantánea"
78 | },
79 | "home": {
80 | "status": {
81 | "online_google": "Google en línea"
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/locales/fr.json:
--------------------------------------------------------------------------------
1 | {
2 | "menu": {
3 | "serp_checker": "Vérificateur de SERP",
4 | "light": "Clair",
5 | "dark": "Sombre",
6 | "system": "Système"
7 | },
8 | "frontend": {
9 | "go_to_homepage": "Aller à la page d'accueil",
10 | "page_not_found": "Page non trouvée",
11 | "home": {
12 | "position": "Position",
13 | "type": "Type de SERP",
14 | "title": "Titre",
15 | "results_for": "Résultats pour \"{query}\"",
16 | "views": {
17 | "preview": "Aperçu"
18 | },
19 | "look_up": "Chercher",
20 | "form": {
21 | "query": {
22 | "error": {
23 | "message": "La requête doit comporter au moins 2 caractères."
24 | }
25 | }
26 | },
27 | "faq": {
28 | "title": "FAQ",
29 | "qa1": {
30 | "question": "Comment puis-je améliorer le classement de mon site web sur le SERP ?",
31 | "answer": "Pour améliorer le classement de votre site web sur les SERP, vous pouvez utiliser les méthodes suivantes :\n\n- **Optimisation pour les moteurs de recherche (SEO)** :\nOptimisez le contenu, la structure et le code de votre site web pour améliorer son classement dans les résultats de recherche organique.\n\n- **Recherche de mots-clés** :\nChoisissez et utilisez des mots-clés à fort trafic pertinents pour votre entreprise.\n\n- **Contenu de haute qualité** :\nCréez du contenu précieux, original et pertinent qui répond aux besoins de recherche des utilisateurs.\n\n- **Optimisation des performances du site web** :\nAméliorez la vitesse de chargement de votre site web et sa compatibilité mobile.\n\n- **Acquérir des backlinks de qualité** :\nObtenez des liens d'autres sites web autorisés pour augmenter l'autorité de votre site.\n"
32 | },
33 | "qa2": {
34 | "question": "Quelles sont les fonctionnalités SERP de Google ?",
35 | "answer": "Les fonctionnalités SERP de Google sont des résultats spéciaux qui apparaissent sur la page de résultats des moteurs de recherche, comme les Rich Results. Ceux-ci incluent:\n\n- Extraits optimisés\n- Boîtes \"Les gens demandent aussi\"\n- Panneaux de connaissances\n- Résultats du Local Pack\n- Carrousels de vidéos et d'images\n"
36 | },
37 | "qa3": {
38 | "question": "Pourquoi utiliser un outil de vérification de SERP ?",
39 | "answer": "Un outil de vérification de SERP vous aide à:\n\n- Suivre le classement de votre site web\n- Analyser les SERP de différents pays et régions\n- Voir les SERP dans diverses langues\n- Surveiller la présence des Rich Results\n- Voir les SERP depuis n'importe quel emplacement\n"
40 | },
41 | "qa4": {
42 | "answer": "Oui, notre vérificateur de SERP est gratuit. À l'avenir, il pourrait y avoir certaines limites d'utilisation.",
43 | "question": "Le vérificateur de SERP est-il gratuit pour toujours ?"
44 | },
45 | "qa5": {
46 | "question": "Fournissez-vous une API de vérificateur de SERP ?",
47 | "answer": "Oui, j'ai développé une API de SERP et je la propose via [SERP.ING](https://www.serp.ing). C'est l'API SERP la plus rentable de l'industrie, incluant tous les principaux Rich Results."
48 | }
49 | }
50 | },
51 | "serp": {
52 | "featured_snippets": "Extraits optimisés",
53 | "people_also_ask": "Les gens demandent aussi",
54 | "things_to_know": "À savoir",
55 | "x": "X",
56 | "twitter": {
57 | "post": {
58 | "posted_on": "Publié le"
59 | }
60 | },
61 | "top_stories": {
62 | "title": "Principales actualités"
63 | },
64 | "images": "Images",
65 | "videos": "Vidéos",
66 | "places": "Lieux",
67 | "related_searches": "recherches associées",
68 | "download_csv": "Télécharger CSV"
69 | },
70 | "meta": {
71 | "default": {
72 | "title": "Vérification de SERP - Vérificateur de SERP gratuit pour un classement Google rapide et précis et des Rich Results",
73 | "description": "Utilisez notre vérificateur de SERP gratuit pour analyser les résultats de plus de 230 pays. Obtenez des informations sur les Rich Results, les 100 meilleurs classements et plus encore. Améliorez votre SEO avec la vérification de SERP maintenant !"
74 | }
75 | },
76 | "desktop": "Bureau",
77 | "snapshot": "Instantané"
78 | },
79 | "home": {
80 | "status": {
81 | "online_google": "Google en ligne"
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/locales/it.json:
--------------------------------------------------------------------------------
1 | {
2 | "menu": {
3 | "serp_checker": "Controllo SERP",
4 | "light": "Chiaro",
5 | "dark": "Scuro",
6 | "system": "Sistema"
7 | },
8 | "frontend": {
9 | "go_to_homepage": "Vai alla homepage",
10 | "page_not_found": "Pagina non trovata",
11 | "home": {
12 | "position": "Posizione",
13 | "type": "Tipo di SERP",
14 | "title": "Titolo",
15 | "results_for": "Risultati per \"{query}\"",
16 | "views": {
17 | "preview": "Anteprima"
18 | },
19 | "look_up": "Cerca",
20 | "form": {
21 | "query": {
22 | "error": {
23 | "message": "La query deve contenere almeno 2 caratteri."
24 | }
25 | }
26 | },
27 | "faq": {
28 | "title": "FAQ",
29 | "qa1": {
30 | "question": "Come posso migliorare il posizionamento del mio sito web sulla SERP?",
31 | "answer": "Per migliorare il posizionamento del tuo sito web nei risultati dei motori di ricerca (SERP), puoi utilizzare i seguenti metodi:\n\n- **Ottimizzazione per i motori di ricerca (SEO)**:\nOttimizza il contenuto, la struttura e il codice del tuo sito web per migliorare il suo posizionamento nei risultati di ricerca organica.\n\n- **Ricerca di parole chiave**:\nScegli e utilizza parole chiave ad alto traffico rilevanti per la tua attività.\n\n- **Contenuti di alta qualità**:\nCrea contenuti preziosi, originali e pertinenti che soddisfino le esigenze di ricerca degli utenti.\n\n- **Ottimizzazione delle prestazioni del sito web**:\nMigliora la velocità di caricamento del tuo sito web e la sua compatibilità mobile.\n\n- **Acquisire backlink di qualità**:\nOttieni link da altri siti web autorevoli per aumentare l'autorità del tuo sito.\n"
32 | },
33 | "qa2": {
34 | "question": "Quali sono le funzionalità SERP di Google?",
35 | "answer": "Le funzionalità SERP di Google sono risultati speciali che appaiono nella pagina dei risultati del motore di ricerca, come i Rich Results. Questi includono:\n\n- Featured Snippets\n- Box \"People Also Ask\"\n- Knowledge Panels\n- Risultati del Local Pack\n- Caroselli di video e immagini\n"
36 | },
37 | "qa3": {
38 | "question": "Perché utilizzare uno strumento di verifica della SERP?",
39 | "answer": "Uno strumento di verifica della SERP ti aiuta a:\n\n- Tracciare il posizionamento del tuo sito web\n- Analizzare le SERP di diversi paesi e regioni\n- Visualizzare le SERP in varie lingue\n- Monitorare la presenza di Rich Results\n- Visualizzare le SERP da qualsiasi posizione\n"
40 | },
41 | "qa4": {
42 | "answer": "Sì, il nostro strumento di verifica della SERP è gratuito. In futuro, potrebbero esserci alcune limitazioni di utilizzo.",
43 | "question": "Il verificatore di SERP è gratuito per sempre?"
44 | },
45 | "qa5": {
46 | "question": "Fornite un'API di verifica della SERP?",
47 | "answer": "Sì, ho sviluppato un'API di SERP e la offro tramite [SERP.ING](https://www.serp.ing). È l'API SERP più conveniente del settore, inclusi tutti i principali Rich Results."
48 | }
49 | }
50 | },
51 | "serp": {
52 | "featured_snippets": "Featured Snippets",
53 | "people_also_ask": "People Also Ask",
54 | "things_to_know": "Cose da sapere",
55 | "x": "X",
56 | "twitter": {
57 | "post": {
58 | "posted_on": "Pubblicato il"
59 | }
60 | },
61 | "top_stories": {
62 | "title": "Notizie principali"
63 | },
64 | "images": "immagini",
65 | "videos": "Video",
66 | "places": "Luoghi",
67 | "related_searches": "Ricerche correlate",
68 | "download_csv": "Scarica CSV"
69 | },
70 | "meta": {
71 | "default": {
72 | "title": "Controllo SERP - Verificatore SERP gratuito per classifiche Google rapide e precise e Rich Results",
73 | "description": "Usa il nostro verificatore di SERP gratuito per analizzare i risultati di oltre 230 paesi. Ottieni informazioni sui Rich Results, le prime 100 classifiche e altro ancora. Migliora la tua SEO con il Controllo SERP ora!"
74 | }
75 | },
76 | "desktop": "Desktop",
77 | "snapshot": "Istantanea"
78 | },
79 | "home": {
80 | "status": {
81 | "online_google": "In linea Google"
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/locales/ja.json:
--------------------------------------------------------------------------------
1 | {
2 | "menu": {
3 | "serp_checker": "SERPチェッカー",
4 | "light": "ライト",
5 | "dark": "ダーク",
6 | "system": "システム"
7 | },
8 | "frontend": {
9 | "go_to_homepage": "ホームページへ",
10 | "page_not_found": "ページが見つかりません",
11 | "home": {
12 | "position": "位置",
13 | "type": "SERPタイプ",
14 | "title": "タイトル",
15 | "results_for": "\"{query}\"の結果",
16 | "views": {
17 | "preview": "プレビュー"
18 | },
19 | "look_up": "検索",
20 | "form": {
21 | "query": {
22 | "error": {
23 | "message": "クエリは少なくとも2文字である必要があります。"
24 | }
25 | }
26 | },
27 | "faq": {
28 | "title": "よくある質問",
29 | "qa1": {
30 | "question": "ウェブサイトのランキングを改善するにはどうすればよいですか?",
31 | "answer": "検索エンジン結果ページ(SERP)でウェブサイトのランキングを改善するには、以下の方法を使用できます:\n\n- **検索エンジン最適化(SEO)**:\nウェブサイトのコンテンツ、構造、コードを最適化して、オーガニック検索結果でのランキングを向上させます。\n\n- **キーワードリサーチ**:\nビジネスに関連する高トラフィックのキーワードを選択して使用します。\n\n- **高品質なコンテンツ**:\nユーザーの検索ニーズに応える価値ある、オリジナルで関連性の高いコンテンツを作成します。\n\n- **ウェブサイトのパフォーマンス最適化**:\nウェブサイトの読み込み速度とモバイル互換性を向上させます。\n\n- **高品質なバックリンクの取得**:\n他の権威あるウェブサイトからリンクを取得して、サイトの権威を高めます。\n"
32 | },
33 | "qa2": {
34 | "question": "GoogleのSERP機能とは何ですか?",
35 | "answer": "GoogleのSERP機能は、検索エンジンの結果ページに表示される特別な結果で、リッチリザルトなどがあります。これには以下が含まれます:\n\n- フィーチャードスニペット\n- People Also Askボックス\n- ナレッジパネル\n- ローカルパックの結果\n- ビデオおよび画像のカルーセル\n"
36 | },
37 | "qa3": {
38 | "question": "なぜSERPチェッカーツールを使用するのですか?",
39 | "answer": "SERPチェッカーツールは以下のことに役立ちます:\n\n- ウェブサイトのランキングを追跡\n- 異なる国や地域のSERPを分析\n- 様々な言語のSERPを表示\n- リッチリザルトの存在を監視\n- どの場所からでもSERPを表示\n"
40 | },
41 | "qa4": {
42 | "answer": "はい、私たちのSERPチェッカーは無料です。将来的には、使用制限が設けられる可能性があります。",
43 | "question": "SERPチェッカーは永久に無料ですか?"
44 | },
45 | "qa5": {
46 | "question": "SERPチェッカーAPIを提供していますか?",
47 | "answer": "はい、私はSERP APIを開発し、[SERP.ING](https://www.serp.ing)を通じて提供しています。業界で最もコスト効果の高いSERP APIであり、主要なリッチリザルトのすべてを含んでいます。"
48 | }
49 | }
50 | },
51 | "serp": {
52 | "featured_snippets": "フィーチャードスニペット",
53 | "people_also_ask": "People Also Ask",
54 | "things_to_know": "知っておくべきこと",
55 | "x": "X",
56 | "twitter": {
57 | "post": {
58 | "posted_on": "投稿日"
59 | }
60 | },
61 | "top_stories": {
62 | "title": "トップストーリー"
63 | },
64 | "images": "画像",
65 | "videos": "動画",
66 | "places": "場所",
67 | "related_searches": "関連検索",
68 | "download_csv": "CSVをダウンロード"
69 | },
70 | "meta": {
71 | "default": {
72 | "title": "SERPチェック - 高速で正確なGoogleランクとリッチリザルトのための無料SERPチェッカー",
73 | "description": "私たちの無料SERPチェッカーを使用して、230以上の国の結果を分析します。リッチリザルト、トップ100ランキングなどの洞察を得ます。今すぐSERPチェックでSEOを向上させましょう!"
74 | }
75 | },
76 | "desktop": "デスクトップ",
77 | "snapshot": "スナップショット"
78 | },
79 | "home": {
80 | "status": {
81 | "online_google": "オンライングーグル"
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/locales/ko.json:
--------------------------------------------------------------------------------
1 | {
2 | "menu": {
3 | "serp_checker": "SERP 체커",
4 | "light": "라이트",
5 | "dark": "다크",
6 | "system": "시스템"
7 | },
8 | "frontend": {
9 | "go_to_homepage": "홈페이지로 이동",
10 | "page_not_found": "페이지를 찾을 수 없습니다",
11 | "home": {
12 | "position": "위치",
13 | "type": "SERP 유형",
14 | "title": "제목",
15 | "results_for": "\"{query}\"에 대한 결과",
16 | "views": {
17 | "preview": "미리보기"
18 | },
19 | "look_up": "검색",
20 | "form": {
21 | "query": {
22 | "error": {
23 | "message": "쿼리는 최소 2자 이상이어야 합니다."
24 | }
25 | }
26 | },
27 | "faq": {
28 | "title": "자주 묻는 질문",
29 | "qa1": {
30 | "question": "웹사이트의 순위를 어떻게 개선할 수 있나요?",
31 | "answer": "SERP에서 웹사이트의 랭킹을 향상시키는 방법은 다음과 같습니다:\n\n- **검색 엔진 최적화 (SEO)**:\n 웹사이트의 콘텐츠, 구조, 코드를 최적화하여 유기적 검색 결과에서의 랭킹을 향상시킵니다.\n\n- **키워드 연구**:\n 비즈니스와 관련이 깊고 고트래픽의 키워드를 선택하고 사용합니다.\n\n- **고품질 콘텐츠**:\n 사용자의 검색 요구를 충족시키는 가치 있는 원본이고 관련성 있는 콘텐츠를 작성합니다.\n\n- **웹사이트 성능 최적화**:\n 웹사이트의 로딩 속도와 모바일 호환성을 향상시킵니다.\n\n- **고품질 백링크 확보**:\n 다른 권위 있는 웹사이트로부터 링크를 획득하여 사이트의 권위를 높입니다.\n"
32 | },
33 | "qa2": {
34 | "question": "Google의 SERP 기능이란 무엇인가요?",
35 | "answer": "Google의 SERP 기능은 검색 엔진 결과 페이지에 표시되는 특별한 결과로, 리치 결과 등이 있습니다. 여기에는 다음이 포함됩니다:\n\n- 추천 스니펫\n- People Also Ask 상자\n- 지식 패널\n- 로컬 팩 결과\n- 비디오 및 이미지 캐러셀\n"
36 | },
37 | "qa3": {
38 | "question": "왜 SERP 체커 도구를 사용해야 하나요?",
39 | "answer": "SERP 체커 도구는 다음에 도움이 됩니다:\n\n- 웹사이트의 순위 추적\n- 다른 국가 및 지역의 SERP 분석\n- 다양한 언어의 SERP 보기\n- 리치 결과의 존재 모니터링\n- 어느 위치에서나 SERP 보기\n"
40 | },
41 | "qa4": {
42 | "answer": "네, 우리의 SERP 체커는 무료입니다. 미래에는 사용 한도가 있을 수 있습니다.",
43 | "question": "SERP 체커는 영원히 무료인가요?"
44 | },
45 | "qa5": {
46 | "question": "SERP 체커 API를 제공하나요?",
47 | "answer": "네, 저는 SERP API를 개발했으며 [SERP.ING](https://www.serp.ing)을 통해 제공합니다. 이는 업계에서 가장 비용 효율적인 SERP API로, 주요 리치 결과를 모두 포함합니다."
48 | }
49 | }
50 | },
51 | "serp": {
52 | "featured_snippets": "추천 스니펫",
53 | "people_also_ask": "People Also Ask",
54 | "things_to_know": "알아야 할 사항",
55 | "x": "X",
56 | "twitter": {
57 | "post": {
58 | "posted_on": "게시일"
59 | }
60 | },
61 | "top_stories": {
62 | "title": "최신 뉴스"
63 | },
64 | "images": "이미지",
65 | "videos": "비디오",
66 | "places": "장소",
67 | "related_searches": "관련 검색어",
68 | "download_csv": "CSV 다운로드"
69 | },
70 | "meta": {
71 | "default": {
72 | "title": "SERP 체크 - 빠르고 정확한 Google 순위 및 리치 결과를 위한 무료 SERP 체커",
73 | "description": "무료 SERP 체커를 사용하여 230개 이상의 국가의 결과를 분석하세요. 리치 결과, 상위 100개 순위 등에 대한 통찰력을 얻습니다. 지금 SERP 체크로 SEO를 향상시키세요!"
74 | }
75 | },
76 | "desktop": "데스크탑",
77 | "snapshot": "스냅 사진"
78 | },
79 | "home": {
80 | "status": {
81 | "online_google": "온라인 구글"
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/locales/nl.json:
--------------------------------------------------------------------------------
1 | {
2 | "menu": {
3 | "serp_checker": "SERP Checker",
4 | "light": "Licht",
5 | "dark": "Donker",
6 | "system": "Systeem"
7 | },
8 | "frontend": {
9 | "go_to_homepage": "Ga naar homepage",
10 | "page_not_found": "Pagina niet gevonden",
11 | "home": {
12 | "position": "Positie",
13 | "type": "SERP Type",
14 | "title": "Titel",
15 | "results_for": "Resultaten voor \"{query}\"",
16 | "views": {
17 | "preview": "Voorvertoning"
18 | },
19 | "look_up": "Opzoeken",
20 | "form": {
21 | "query": {
22 | "error": {
23 | "message": "Query moet minimaal 2 tekens bevatten."
24 | }
25 | }
26 | },
27 | "faq": {
28 | "title": "Veelgestelde vragen",
29 | "qa1": {
30 | "question": "Hoe kan ik de ranking van mijn website verbeteren?",
31 | "answer": "Om de ranking van je website in de zoekresultaten van zoekmachines te verbeteren, kun je de volgende methoden gebruiken:\n\n- **Zoekmachineoptimalisatie (SEO)**:\n Optimaliseer de inhoud, structuur en code van je website om de ranking in organische zoekresultaten te verbeteren.\n\n- **Keywordonderzoek**:\n Kies en gebruik veelgebruikte zoekwoorden die relevant zijn voor je bedrijf.\n\n- **Hoogwaardige inhoud**:\n Creëer waardevolle, originele en relevante inhoud die voldoet aan de zoekbehoeften van gebruikers.\n\n- **Optimalisatie van websiteprestaties**:\n Verbeter de laadsnelheid en mobiele compatibiliteit van je website.\n\n- **Verkrijgen van kwalitatieve backlinks**:\n Verkrijg links van andere gezaghebbende websites om de autoriteit van je site te verhogen.\n"
32 | },
33 | "qa2": {
34 | "question": "Wat zijn Google SERP-functies?",
35 | "answer": "Google SERP-functies zijn speciale resultaten die verschijnen op de zoekresultatenpagina, zoals rijke resultaten. Deze omvatten:\n\n- Uitgelichte fragmenten\n- Mensen vragen ook\n- Kenniskaarten\n- Lokale pakketten\n- Video- en afbeeldingscarrousels\n"
36 | },
37 | "qa3": {
38 | "question": "Waarom een SERP Checker Tool gebruiken?",
39 | "answer": "Een SERP Checker Tool helpt u:\n\n- De ranking van uw website bijhouden\n- SERP's analyseren uit verschillende landen en regio's\n- SERP's in verschillende talen bekijken\n- De aanwezigheid van rijke resultaten monitoren\n- SERP's vanuit elke locatie bekijken\n"
40 | },
41 | "qa4": {
42 | "answer": "Ja, onze SERP Checker is gratis. In de toekomst kunnen er enkele gebruikslimieten zijn.",
43 | "question": "Is de SERP Checker voor altijd gratis?"
44 | },
45 | "qa5": {
46 | "question": "Biedt u een SERP Checker API aan?",
47 | "answer": "Ja, ik heb een SERP API ontwikkeld en bied deze aan via [SERP.ING](https://www.serp.ing). Het is de meest kosteneffectieve SERP API in de industrie, inclusief alle belangrijke rijke resultaten."
48 | }
49 | }
50 | },
51 | "serp": {
52 | "featured_snippets": "Uitgelichte fragmenten",
53 | "people_also_ask": "Mensen vragen ook",
54 | "things_to_know": "Dingen om te weten",
55 | "x": "X",
56 | "twitter": {
57 | "post": {
58 | "posted_on": "Gepost op"
59 | }
60 | },
61 | "top_stories": {
62 | "title": "Topverhalen"
63 | },
64 | "images": "Afbeeldingen",
65 | "videos": "Videos",
66 | "places": "Plaatsen",
67 | "related_searches": "Verwante zoekopdrachten",
68 | "download_csv": "CSV downloaden"
69 | },
70 | "meta": {
71 | "default": {
72 | "title": "SERP Checker - Gratis SERP Checker voor snelle, nauwkeurige Google Ranking & Rijke Resultaten",
73 | "description": "Gebruik onze gratis SERP Checker om resultaten te analyseren uit meer dan 230 landen. Krijg inzichten in rijke resultaten, top 100 rankings en meer. Verbeter uw SEO nu met SERP Checker!"
74 | }
75 | },
76 | "desktop": "Desktop",
77 | "snapshot": "Momentopname"
78 | },
79 | "home": {
80 | "status": {
81 | "online_google": "Online Googlen"
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/locales/pl.json:
--------------------------------------------------------------------------------
1 | {
2 | "menu": {
3 | "serp_checker": "SERP Checker",
4 | "light": "Jasny",
5 | "dark": "Ciemny",
6 | "system": "System"
7 | },
8 | "frontend": {
9 | "go_to_homepage": "Idź na stronę główną",
10 | "page_not_found": "Strona nie znaleziona",
11 | "home": {
12 | "position": "Pozycja",
13 | "type": "Typ SERP",
14 | "title": "Tytuł",
15 | "results_for": "Wyniki dla \"{query}\"",
16 | "views": {
17 | "preview": "Podgląd"
18 | },
19 | "look_up": "Szukaj",
20 | "form": {
21 | "query": {
22 | "error": {
23 | "message": "Zapytanie musi mieć co najmniej 2 znaki."
24 | }
25 | }
26 | },
27 | "faq": {
28 | "title": "Najczęściej zadawane pytania",
29 | "qa1": {
30 | "question": "Jak mogę poprawić pozycję mojej strony?",
31 | "answer": "Aby poprawić ranking twojej strony internetowej w wynikach wyszukiwania w wyszukiwarkach, możesz skorzystać z następujących metod:\n\n- **Optymalizacja dla wyszukiwarek internetowych (SEO)**:\n Optymalizuj zawartość, strukturę i kod swojej strony internetowej, aby poprawić jej pozycję w organicznych wynikach wyszukiwania.\n\n- **Badanie słów kluczowych**:\n Wybierz i użyj popularnych słów kluczowych związanych z Twoim biznesem.\n\n- **Wysokiej jakości treści**:\n Twórz wartościowe, oryginalne i trafne treści, które spełniają potrzeby wyszukiwania użytkowników.\n\n- **Optymalizacja wydajności strony internetowej**:\n Popraw szybkość ładowania i kompatybilność mobilną swojej strony internetowej.\n\n- **Zdobycie wysokiej jakości backlinków**:\n Zdobądź linki od innych autorytatywnych stron internetowych, aby zwiększyć autorytet Twojej strony.\n\n"
32 | },
33 | "qa2": {
34 | "question": "Czym są funkcje SERP w Google?",
35 | "answer": "Funkcje SERP w Google to specjalne wyniki, które pojawiają się na stronie wyników wyszukiwania, takie jak Rich Results. Obejmują one:\n\n- Wyróżnione fragmenty\n- Pytania ludzi\n- Panele wiedzy\n- Lokalne pakiety wyników\n- Karuzele wideo i obrazów\n"
36 | },
37 | "qa3": {
38 | "question": "Dlaczego warto używać narzędzia SERP Checker?",
39 | "answer": "Narzędzie SERP Checker pomaga:\n\n- Śledzić pozycję Twojej strony\n- Analizować wyniki SERP z różnych krajów i regionów\n- Przeglądać wyniki SERP w różnych językach\n- Monitorować obecność Rich Results\n- Przeglądać wyniki SERP z dowolnej lokalizacji\n"
40 | },
41 | "qa4": {
42 | "answer": "Tak, nasz SERP Checker jest darmowy. W przyszłości mogą pojawić się pewne limity użycia.",
43 | "question": "Czy SERP Checker będzie zawsze darmowy?"
44 | },
45 | "qa5": {
46 | "question": "Czy oferujecie API SERP Checker?",
47 | "answer": "Tak, opracowałem API SERP i oferuję je przez [SERP.ING](https://www.serp.ing). Jest to najbardziej opłacalne API SERP w branży, obejmujące wszystkie główne Rich Results."
48 | }
49 | }
50 | },
51 | "serp": {
52 | "featured_snippets": "Wyróżnione fragmenty",
53 | "people_also_ask": "Pytania ludzi",
54 | "things_to_know": "Rzeczy, które warto wiedzieć",
55 | "x": "X",
56 | "twitter": {
57 | "post": {
58 | "posted_on": "Opublikowano"
59 | }
60 | },
61 | "top_stories": {
62 | "title": "Najważniejsze historie"
63 | },
64 | "images": "Obrazy",
65 | "videos": "Filmy",
66 | "places": "Miejsca",
67 | "related_searches": "Powiązane Wyszukiwania",
68 | "download_csv": "Pobierz plik CSV"
69 | },
70 | "meta": {
71 | "default": {
72 | "title": "SERP Checker - Darmowy SERP Checker do szybkiego, dokładnego sprawdzania rankingów Google i Rich Results",
73 | "description": "Użyj naszego darmowego SERP Checkera, aby analizować wyniki z ponad 230 krajów. Zdobądź informacje o Rich Results, top 100 rankingach i więcej. Popraw swoje SEO z SERP Checker już teraz!"
74 | }
75 | },
76 | "desktop": "Komputer",
77 | "snapshot": "Migawka"
78 | },
79 | "home": {
80 | "status": {
81 | "online_google": "Internetowe Google"
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/locales/ru.json:
--------------------------------------------------------------------------------
1 | {
2 | "menu": {
3 | "serp_checker": "SERP Checker",
4 | "light": "Светлая",
5 | "dark": "Темная",
6 | "system": "Системная"
7 | },
8 | "frontend": {
9 | "go_to_homepage": "Перейти на главную",
10 | "page_not_found": "Страница не найдена",
11 | "home": {
12 | "position": "Позиция",
13 | "type": "Тип SERP",
14 | "title": "Заголовок",
15 | "results_for": "Результаты для \"{query}\"",
16 | "views": {
17 | "preview": "Просмотр"
18 | },
19 | "look_up": "Поиск",
20 | "form": {
21 | "query": {
22 | "error": {
23 | "message": "Запрос должен содержать минимум 2 символа."
24 | }
25 | }
26 | },
27 | "faq": {
28 | "title": "Часто задаваемые вопросы",
29 | "qa1": {
30 | "question": "Как улучшить ранжирование моего сайта в SERP?",
31 | "answer": "Чтобы улучшить ранжирование вашего сайта в результатах поиска (SERP), вы можете использовать следующие методы:\n\n- **Поисковая оптимизация (SEO)**:\n Оптимизируйте контент, структуру и код вашего сайта для улучшения его позиций в органических результатах поиска.\n\n- **Поиск ключевых слов**:\n Выбирайте и используйте популярные ключевые слова, соответствующие вашему бизнесу.\n\n- **Высококачественный контент**:\n Создавайте ценные, оригинальные и релевантные материалы, отвечающие запросам пользователей.\n\n- **Оптимизация производительности сайта**:\n Улучшайте скорость загрузки и мобильную совместимость вашего сайта.\n\n- **Получение качественных обратных ссылок**:\n Получайте ссылки от других авторитетных веб-сайтов для повышения авторитетности вашего сайта.\n"
32 | },
33 | "qa2": {
34 | "question": "Что такое функции SERP в Google?",
35 | "answer": "Функции SERP в Google - это специальные результаты, которые появляются на странице результатов поиска, такие как Rich Results. Они включают:\n\n- Выделенные фрагменты\n- Вопросы людей (People Also Ask)\n- Панели знаний (Knowledge Panels)\n- Локальные блоки (Local Pack)\n- Видео и изображения (Video and Image Carousels)\n"
36 | },
37 | "qa3": {
38 | "question": "Зачем использовать инструмент SERP Checker?",
39 | "answer": "Инструмент SERP Checker помогает вам:\n\n- Отслеживать ранжирование вашего сайта\n- Анализировать результаты SERP из разных стран и регионов\n- Просматривать результаты SERP на разных языках\n- Мониторить наличие Rich Results\n- Просматривать результаты SERP из любой локации\n"
40 | },
41 | "qa4": {
42 | "answer": "Да, наш SERP Checker бесплатен. В будущем могут быть введены ограничения по использованию.",
43 | "question": "Будет ли SERP Checker бесплатным навсегда?"
44 | },
45 | "qa5": {
46 | "question": "Предоставляете ли вы API для SERP Checker?",
47 | "answer": "Да, я разработал API для SERP и предлагаю его через [SERP.ING](https://www.serp.ing). Это самое экономичное API для SERP в индустрии, включающее все основные Rich Results."
48 | }
49 | }
50 | },
51 | "serp": {
52 | "featured_snippets": "Выделенные фрагменты",
53 | "people_also_ask": "Вопросы людей",
54 | "things_to_know": "Важные моменты",
55 | "x": "X",
56 | "twitter": {
57 | "post": {
58 | "posted_on": "Опубликовано"
59 | }
60 | },
61 | "top_stories": {
62 | "title": "Топ новости"
63 | },
64 | "images": "Изображений",
65 | "videos": "Видео",
66 | "places": "Места",
67 | "related_searches": "Похожие Запросы",
68 | "download_csv": "Скачать CSV-файл"
69 | },
70 | "meta": {
71 | "default": {
72 | "title": "Проверка SERP - Бесплатный инструмент для быстрой и точной проверки ранжирования Google и Rich Results",
73 | "description": "Используйте наш бесплатный инструмент SERP Checker для анализа результатов из более чем 230 стран. Получите информацию о Rich Results, топ-100 ранжировании и многое другое. Улучшите свое SEO с помощью SERP Checker прямо сейчас!"
74 | }
75 | },
76 | "desktop": "Десктоп",
77 | "snapshot": "Снимок"
78 | },
79 | "home": {
80 | "status": {
81 | "online_google": "Онлайн Гугл"
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/locales/sv.json:
--------------------------------------------------------------------------------
1 | {
2 | "menu": {
3 | "serp_checker": "Serp Checker",
4 | "light": "Ljus",
5 | "dark": "Mörk",
6 | "system": "System"
7 | },
8 | "frontend": {
9 | "go_to_homepage": "Gå till startsidan",
10 | "page_not_found": "Sidan kunde inte hittas",
11 | "home": {
12 | "position": "Position",
13 | "type": "Serp-typ",
14 | "title": "Titel",
15 | "results_for": "Resultat för \"{query}\"",
16 | "views": {
17 | "preview": "Förhandsvisning"
18 | },
19 | "look_up": "Sök upp",
20 | "form": {
21 | "query": {
22 | "error": {
23 | "message": "Frågan måste vara minst 2 tecken lång."
24 | }
25 | }
26 | },
27 | "faq": {
28 | "title": "Vanliga frågor",
29 | "qa1": {
30 | "question": "Hur kan jag förbättra min webbplats rangordning i SERP?",
31 | "answer": "För att förbättra din webbplats ranking på SERP (sökmotorresultatsidan) kan du använda följande metoder:\n\n- **Sökmotoroptimering (SEO)**:\n Optimera din webbplats innehåll, struktur och kod för att förbättra dess ranking i organiska sökresultat.\n\n- **Sökordsanalys**:\n Välj och använd högtrafikerade sökord relevanta för ditt företag.\n\n- **Högkvalitativt innehåll**:\n Skapa värdefullt, originalt och relevant innehåll som möter användarnas sökbehov.\n\n- **Optimering av webbplatsprestanda**:\n Förbättra din webbplats laddningstid och mobilkompatibilitet.\n\n- **Få högkvalitativa tillbakalänkar**:\n Skaffa länkar från andra auktoritära webbplatser för att öka din webbplats auktoritet.\n"
32 | },
33 | "qa2": {
34 | "question": "Vad är Google SERP-funktioner?",
35 | "answer": "Google SERP-funktioner är speciella resultat som visas på sökmotorresultatsidan, såsom Rika resultat. Dessa inkluderar:\n\n- Framträdande utdrag\n- Frågor som andra också frågar\n- Kunskapspaneler\n- Lokala packresultat\n- Video- och bildkaruseller\n"
36 | },
37 | "qa3": {
38 | "question": "Varför använda en SERP Checker-verktyg?",
39 | "answer": "Ett SERP Checker-verktyg hjälper dig att:\n\n- Spåra din webbplats rangordning\n- Analysera SERP från olika länder och regioner\n- Visa SERP på olika språk\n- Övervaka närvaron av Rika resultat\n- Visa SERP från vilken plats som helst\n"
40 | },
41 | "qa4": {
42 | "question": "Är SERP Checker gratis för alltid?",
43 | "answer": "Ja, vår SERP checker är gratis. I framtiden kan det finnas vissa användningsbegränsningar."
44 | },
45 | "qa5": {
46 | "question": "Erbjuder ni en SERP Checker API?",
47 | "answer": "Ja, jag har utvecklat en SERP API och erbjuder den genom [SERP.ING](https://www.serp.ing). Det är den mest kostnadseffektiva SERP API:n i branschen, inklusive alla stora Rika resultat."
48 | }
49 | }
50 | },
51 | "serp": {
52 | "featured_snippets": "Framträdande utdrag",
53 | "people_also_ask": "Frågor som andra också frågar",
54 | "things_to_know": "Saker att veta",
55 | "x": "X",
56 | "twitter": {
57 | "post": {
58 | "posted_on": "Publicerad den"
59 | }
60 | },
61 | "top_stories": {
62 | "title": "Toppnyheter"
63 | },
64 | "images": "Bilder",
65 | "videos": "videoklipp",
66 | "places": "Platser",
67 | "related_searches": "Relaterade sökningar",
68 | "download_csv": "Ladda ner CSV"
69 | },
70 | "meta": {
71 | "default": {
72 | "title": "SERP-kontroll - Gratis SERP Checker för snabb och exakt Google Rank & Rika resultat",
73 | "description": "Använd vår gratis SERP checker för att analysera resultat från 230+ länder. Få insikter om Rika resultat, topp 100 rankningar och mer. Öka din SEO med SERP-kontroll nu!"
74 | }
75 | },
76 | "desktop": "Skrivbord",
77 | "snapshot": "Ögonblicksbild"
78 | },
79 | "home": {
80 | "status": {
81 | "online_google": "Google online"
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/locales/tr.json:
--------------------------------------------------------------------------------
1 | {
2 | "menu": {
3 | "serp_checker": "Serp Kontrolcüsü",
4 | "light": "Açık",
5 | "dark": "Koyu",
6 | "system": "Sistem"
7 | },
8 | "frontend": {
9 | "go_to_homepage": "Ana sayfaya git",
10 | "page_not_found": "Sayfa bulunamadı",
11 | "home": {
12 | "position": "Pozisyon",
13 | "type": "Serp Türü",
14 | "title": "Başlık",
15 | "results_for": "\"{query}\" için sonuçlar",
16 | "views": {
17 | "preview": "Önizleme"
18 | },
19 | "look_up": "Ara",
20 | "form": {
21 | "query": {
22 | "error": {
23 | "message": "Arama sorgusu en az 2 karakter olmalıdır."
24 | }
25 | }
26 | },
27 | "faq": {
28 | "title": "SSS",
29 | "qa1": {
30 | "question": "Web sitemin SERP üzerindeki sıralamasını nasıl iyileştirebilirim?",
31 | "answer": "För att förbättra din webbplats ranking på SERP (sökmotorresultatsidan) kan du använda följande metoder:\n\n- **Sökmotoroptimering (SEO)**:\n Optimera din webbplats innehåll, struktur och kod för att förbättra dess ranking i organiska sökresultat.\n\n- **Sökordsanalys**:\n Välj och använd högtrafikerade sökord relevanta för ditt företag.\n\n- **Högkvalitativt innehåll**:\n Skapa värdefullt, originalt och relevant innehåll som möter användarnas sökbehov.\n\n- **Optimering av webbplatsprestanda**:\n Förbättra din webbplats laddningstid och mobilkompatibilitet.\n\n- **Få högkvalitativa tillbakalänkar**:\n Skaffa länkar från andra auktoritära webbplatser för att öka din webbplats auktoritet.\n"
32 | },
33 | "qa2": {
34 | "question": "Google SERP Özellikleri nedir?",
35 | "answer": "Google SERP özellikleri, zengin sonuçlar gibi arama motoru sonuç sayfasında görünen özel sonuçlardır. Bunlar şunları içerir:\n\n- Öne Çıkan Parçacıklar\n- İnsanlar da Sordu kutuları\n- Bilgi Panelleri\n- Yerel Paket sonuçları\n- Video ve Görüntü Karuselleri\n"
36 | },
37 | "qa3": {
38 | "question": "Neden Bir SERP Kontrol Aracı Kullanmalıyım?",
39 | "answer": "Bir SERP kontrol aracı, aşağıdaki şekillerde size yardımcı olur:\n\n- Web sitenizin sıralamasını takip etmek\n- Farklı ülkeler ve bölgelerden SERP'leri analiz etmek\n- Çeşitli dillerde SERP'leri görüntülemek\n- Zengin Sonuçların varlığını izlemek\n- Herhangi bir konumdan SERP'leri görüntülemek\n"
40 | },
41 | "qa4": {
42 | "answer": "Evet, SERP kontrolcümüz ücretsizdir. Gelecekte bazı kullanım sınırlamaları olabilir.",
43 | "question": "SERP Kontrolcüsü Sonsuza Kadar Ücretsiz mi?"
44 | },
45 | "qa5": {
46 | "question": "Bir SERP Kontrolcüsü API Sunuyor musunuz?",
47 | "answer": "Evet, bir SERP API geliştirdim ve [SERP.ING](https://www.serp.ing) aracılığıyla sunuyorum. Endüstrideki en maliyet etkin SERP API'sidir ve tüm önemli Zengin Sonuçları içerir."
48 | }
49 | }
50 | },
51 | "serp": {
52 | "featured_snippets": "Öne Çıkan Parçacıklar",
53 | "people_also_ask": "İnsanlar da Sordu",
54 | "things_to_know": "Bilmeniz Gerekenler",
55 | "x": "X",
56 | "twitter": {
57 | "post": {
58 | "posted_on": "Yayınlandı"
59 | }
60 | },
61 | "top_stories": {
62 | "title": "En Çok Okunan Haberler"
63 | },
64 | "images": "Görüntüler",
65 | "videos": "Videolar",
66 | "places": "Yer",
67 | "related_searches": "ilgili aramalar",
68 | "download_csv": "CSV'yi indirin"
69 | },
70 | "meta": {
71 | "default": {
72 | "title": "SERP Kontrol - Hızlı, Doğru Google Sıralama ve Zengin Sonuçlar için Ücretsiz SERP Kontrolcüsü",
73 | "description": "Ücretsiz SERP kontrolcümüzü kullanarak 230'dan fazla ülkeden sonuçları analiz edin. Zengin Sonuçlar, ilk 100 sıralama ve daha fazlası hakkında bilgi edinin. SEO'nuzu SERP Kontrol ile güçlendirin!"
74 | }
75 | },
76 | "desktop": "Masaüstü",
77 | "snapshot": "Enstantane fotoğraf"
78 | },
79 | "home": {
80 | "status": {
81 | "online_google": "Çevrimiçi Google"
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/locales/zh.json:
--------------------------------------------------------------------------------
1 | {
2 | "menu": {
3 | "serp_checker": "SERP检测器",
4 | "light": "亮色",
5 | "dark": "暗色",
6 | "system": "系统"
7 | },
8 | "frontend": {
9 | "go_to_homepage": "返回首页",
10 | "page_not_found": "页面未找到",
11 | "home": {
12 | "position": "位置",
13 | "type": "SERP类型",
14 | "title": "标题",
15 | "results_for": "“{query}”的搜索结果",
16 | "views": {
17 | "preview": "预览"
18 | },
19 | "look_up": "查找",
20 | "form": {
21 | "query": {
22 | "error": {
23 | "message": "查询至少需要2个字符。"
24 | }
25 | }
26 | },
27 | "faq": {
28 | "title": "常见问题",
29 | "qa1": {
30 | "question": "如何提高我的网站在SERP上的排名?",
31 | "answer": "要提高你的网站在搜索引擎结果页面(SERP)上的排名,可以采用以下方法:\n\n- **搜索引擎优化(SEO)**:\n 优化网站内容、结构和代码,提升在有机搜索结果中的排名。\n\n- **关键词研究**:\n 选择并使用与你的业务相关的高流量关键词。\n\n- **高质量内容**:\n 创建有价值、原创和与用户搜索需求相关的内容。\n\n- **网站性能优化**:\n 提高网站的加载速度和移动设备兼容性。\n\n- **获取高质量的反向链接**:\n 从其他权威网站获取链接,提升你网站的权威性。\n"
32 | },
33 | "qa2": {
34 | "question": "什么是Google SERP特性?",
35 | "answer": "Google SERP特性是出现在搜索引擎结果页面上的特殊结果,例如丰富的结果。其中包括:\n\n- 突出显示的摘录\n- 人们也在问的框\n- 知识面板\n- 本地包结果\n- 视频和图像轮播\n"
36 | },
37 | "qa3": {
38 | "question": "为什么要使用SERP检测工具?",
39 | "answer": "SERP检测工具可以帮助您:\n\n- 跟踪您网站的排名\n- 分析来自不同国家和地区的SERP\n- 查看各种语言的SERP\n- 监控丰富结果的存在\n- 查看任意位置的SERP\n"
40 | },
41 | "qa4": {
42 | "answer": "是的,我们的SERP检测工具是免费的。将来可能会有一些使用限制。",
43 | "question": "SERP检测工具永久免费吗?"
44 | },
45 | "qa5": {
46 | "question": "您提供SERP检测工具的API吗?",
47 | "answer": "是的,我开发了一个SERP API,并通过[SERP.ING](https://www.serp.ing)提供。这是行业内成本效益最高的SERP API,包括所有主要的丰富结果。"
48 | }
49 | }
50 | },
51 | "serp": {
52 | "featured_snippets": "突出显示的摘录",
53 | "people_also_ask": "人们也在问",
54 | "things_to_know": "需要了解的内容",
55 | "x": "X",
56 | "twitter": {
57 | "post": {
58 | "posted_on": "发布于"
59 | }
60 | },
61 | "top_stories": {
62 | "title": "热门新闻"
63 | },
64 | "images": "图片",
65 | "videos": "视频",
66 | "places": "地点",
67 | "related_searches": "相关搜索",
68 | "download_csv": "下载 CSV 文件"
69 | },
70 | "meta": {
71 | "default": {
72 | "title": "SERP检测 - 免费的快速、准确的Google排名和丰富结果检测工具",
73 | "description": "使用我们的免费SERP检测工具分析来自230多个国家的结果。了解丰富结果、前100名排名等信息。立即通过SERP检测增强您的SEO!"
74 | }
75 | },
76 | "desktop": "桌面版",
77 | "snapshot": "快照"
78 | },
79 | "home": {
80 | "status": {
81 | "online_google": "在线谷歌"
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/middleware.ts:
--------------------------------------------------------------------------------
1 | import { appConfig } from "@/config";
2 | import createMiddleware from "next-intl/middleware";
3 | import { NextRequest } from "next/server";
4 |
5 | export default async function middleware(req: NextRequest) {
6 | const reqHeaders = new Headers(req.headers);
7 | reqHeaders.set('x-request-url', req.url);
8 |
9 | // Create a new request with updated headers
10 | const modifiedRequest = new NextRequest(req.url, {
11 | headers: reqHeaders,
12 | method: req.method,
13 | body: req.body
14 | });
15 | const intlMiddleware = createMiddleware({
16 | locales: appConfig.i18n.locales,
17 | defaultLocale: appConfig.i18n.defaultLocale,
18 | localePrefix: "as-needed",
19 | localeDetection: false,
20 | alternateLinks: true
21 | });
22 |
23 | return intlMiddleware(modifiedRequest);
24 | }
25 |
26 | export const config = {
27 | matcher: ["/((?!api|_next|.*\\..*).*)"],
28 | };
29 |
--------------------------------------------------------------------------------
/models/GeoTrgets.ts:
--------------------------------------------------------------------------------
1 | import { parseString } from '@fast-csv/parse';
2 | import fs from 'fs';
3 | import path from 'path';
4 |
5 | export type Row = Record;
6 | const filePath = path.join(process.cwd(), 'data', 'geotargets.csv');
7 |
8 | const csvData: Row[] = [];
9 | let dataLoaded = false;
10 |
11 | export default function GeoTargets(): void {
12 | try {
13 | const fileContent = fs.readFileSync(filePath, 'utf-8');
14 | parseString(fileContent, { headers: true })
15 | .on('data', (row: Row) => {
16 | csvData.push(row);
17 | })
18 | .on('end', () => {
19 | dataLoaded = true;
20 | })
21 | .on('error', (error) => {
22 | throw new Error(`Failed to parse CSV: ${error.message}`);
23 | });
24 | } catch (error: any) {
25 | throw new Error(`Failed to read file: ${error.message}`);
26 | }
27 | }
28 |
29 | export { csvData, dataLoaded, GeoTargets };
30 |
31 |
--------------------------------------------------------------------------------
/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | import nextIntlPlugin from "next-intl/plugin";
3 | const withNextIntl = nextIntlPlugin("./i18n.ts");
4 |
5 | const nextConfig = {
6 | eslint: {
7 | dirs: ["app", "lib", "components", "models"],
8 | },
9 | };
10 |
11 | export default withNextIntl(nextConfig);
12 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "serp-checker",
3 | "version": "0.2.0.rc",
4 | "license": "MIT",
5 | "author": "Sead Feng",
6 | "private": true,
7 | "scripts": {
8 | "dev": "next dev",
9 | "build": "next build",
10 | "start": "next start",
11 | "lint": "next lint",
12 | "generate-markdown-data": "tsx bin/generateComponentsMarkdownData.ts",
13 | "add-data": "git add data",
14 | "watch-markdown": "tsx bin/watcher.ts"
15 | },
16 | "dependencies": {
17 | "@hookform/resolvers": "^3.9.0",
18 | "@next/third-parties": "^14.2.5",
19 | "@radix-ui/react-accordion": "^1.2.0",
20 | "@radix-ui/react-alert-dialog": "^1.1.1",
21 | "@radix-ui/react-avatar": "^1.1.0",
22 | "@radix-ui/react-dialog": "^1.1.1",
23 | "@radix-ui/react-dropdown-menu": "^2.1.1",
24 | "@radix-ui/react-label": "^2.1.0",
25 | "@radix-ui/react-popover": "^1.1.1",
26 | "@radix-ui/react-select": "^2.1.1",
27 | "@radix-ui/react-slot": "^1.1.0",
28 | "@radix-ui/react-switch": "^1.1.0",
29 | "@radix-ui/react-toast": "^1.2.1",
30 | "@tanstack/react-table": "^8.19.2",
31 | "axios": "^1.7.2",
32 | "class-variance-authority": "^0.7.0",
33 | "clsx": "^2.1.1",
34 | "cmdk": "^1.0.0",
35 | "deepmerge": "^4.3.1",
36 | "embla-carousel-react": "^8.1.6",
37 | "fast-csv": "^5.0.1",
38 | "lodash": "^4.17.21",
39 | "lucide-react": "^0.400.0",
40 | "next": "14.2.4",
41 | "next-intl": "^3.15.3",
42 | "next-themes": "^0.3.0",
43 | "nextjs-toploader": "^1.6.12",
44 | "react": "^18.3.1",
45 | "react-csv": "^2.2.2",
46 | "react-dom": "^18.3.1",
47 | "react-hook-form": "^7.52.1",
48 | "react-hot-toast": "^2.4.1",
49 | "react-markdown": "^9.0.1",
50 | "rehype-raw": "^7.0.0",
51 | "remark-gfm": "^4.0.0",
52 | "serping": "^1.2.1-beta.7",
53 | "tailwind-merge": "^2.3.0",
54 | "tailwindcss-animate": "^1.0.7",
55 | "usehooks-ts": "^3.1.0",
56 | "zod": "^3.23.8"
57 | },
58 | "devDependencies": {
59 | "@tailwindcss/typography": "^0.5.13",
60 | "@types/lodash": "^4.17.6",
61 | "@types/node": "^20",
62 | "@types/react": "^18",
63 | "@types/react-csv": "^1.1.10",
64 | "@types/react-dom": "^18",
65 | "@typescript-eslint/eslint-plugin": "^7.16.0",
66 | "@typescript-eslint/parser": "^7.16.0",
67 | "chokidar": "^3.6.0",
68 | "eslint": "^8.57.0",
69 | "eslint-config-next": "14.2.4",
70 | "eslint-plugin-import": "^2.29.1",
71 | "eslint-plugin-react": "^7.34.3",
72 | "eslint-plugin-react-hooks": "^4.6.2",
73 | "postcss": "^8",
74 | "pre-commit": "^1.2.2",
75 | "tailwindcss": "^3.4.1",
76 | "tsx": "^4.16.2",
77 | "typescript": "^5.5.3"
78 | },
79 | "pre-commit": [
80 | "lint",
81 | "generate-markdown-data",
82 | "add-data"
83 | ]
84 | }
--------------------------------------------------------------------------------
/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/public/apiKey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/serping/serp-checker/27c23062dbdadfdf56210c7a7929f47079b2dfbf/public/apiKey.png
--------------------------------------------------------------------------------
/public/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/serping/serp-checker/27c23062dbdadfdf56210c7a7929f47079b2dfbf/public/logo.png
--------------------------------------------------------------------------------
/public/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/schema/index.ts:
--------------------------------------------------------------------------------
1 | import { appConfig } from '@/config';
2 | import z from 'zod';
3 | export const HomeFormSchema = z.object({
4 | query: z.string().min(2, {
5 | message: "query must be at least 2 characters.",
6 | }),
7 | locale: z.string(),
8 | country: z.string(),
9 | device: z.enum(appConfig.devices),
10 | location: z.string().optional(),
11 | snapshot: z.enum(["on", "off"])
12 | })
13 | export type HomeFormValues = z.infer;
14 |
15 | export const LocationSchema = z.object({
16 | "Criteria ID": z.string(),
17 | Name: z.string(),
18 | "Canonical Name": z.string(),
19 | "Parent ID": z.string(),
20 | "Country Code": z.string(),
21 | "Target Type": z.string(),
22 | Status: z.string()
23 | })
24 |
25 | export type Location = z.infer;
26 |
27 | export type ComboboxFramework = {
28 | disabled?: boolean;
29 | icon?: React.ReactNode;
30 | short_label?: string;
31 | code?: string;
32 | value: string;
33 | label: string;
34 | }
35 |
--------------------------------------------------------------------------------
/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from "tailwindcss"
2 | const { fontFamily } = require("tailwindcss/defaultTheme")
3 |
4 | const config = {
5 | darkMode: ["class"],
6 | content: [
7 | './pages/**/*.{ts,tsx}',
8 | './components/**/*.{ts,tsx}',
9 | './app/**/*.{ts,tsx}',
10 | './src/**/*.{ts,tsx}',
11 | ],
12 | prefix: "",
13 | theme: {
14 | container: {
15 | center: true,
16 | padding: "2rem",
17 | screens: {
18 | "2xl": "1400px",
19 | },
20 | },
21 | extend: {
22 | fontFamily: {
23 | sans: ["var(--font-sans)", ...fontFamily.sans],
24 | },
25 | colors: {
26 | border: "hsl(var(--border))",
27 | input: "hsl(var(--input))",
28 | ring: "hsl(var(--ring))",
29 | background: "hsl(var(--background))",
30 | foreground: "hsl(var(--foreground))",
31 | primary: {
32 | DEFAULT: "hsl(var(--primary))",
33 | foreground: "hsl(var(--primary-foreground))",
34 | },
35 | secondary: {
36 | DEFAULT: "hsl(var(--secondary))",
37 | foreground: "hsl(var(--secondary-foreground))",
38 | },
39 | destructive: {
40 | DEFAULT: "hsl(var(--destructive))",
41 | foreground: "hsl(var(--destructive-foreground))",
42 | },
43 | muted: {
44 | DEFAULT: "hsl(var(--muted))",
45 | foreground: "hsl(var(--muted-foreground))",
46 | },
47 | accent: {
48 | DEFAULT: "hsl(var(--accent))",
49 | foreground: "hsl(var(--accent-foreground))",
50 | },
51 | popover: {
52 | DEFAULT: "hsl(var(--popover))",
53 | foreground: "hsl(var(--popover-foreground))",
54 | },
55 | card: {
56 | DEFAULT: "hsl(var(--card))",
57 | foreground: "hsl(var(--card-foreground))",
58 | },
59 | },
60 | borderRadius: {
61 | lg: "var(--radius)",
62 | md: "calc(var(--radius) - 2px)",
63 | sm: "calc(var(--radius) - 4px)",
64 | },
65 | keyframes: {
66 | "accordion-down": {
67 | from: { height: "0" },
68 | to: { height: "var(--radix-accordion-content-height)" },
69 | },
70 | "accordion-up": {
71 | from: { height: "var(--radix-accordion-content-height)" },
72 | to: { height: "0" },
73 | },
74 | },
75 | animation: {
76 | "accordion-down": "accordion-down 0.2s ease-out",
77 | "accordion-up": "accordion-up 0.2s ease-out",
78 | },
79 | },
80 | },
81 | plugins: [require("tailwindcss-animate"), require('@tailwindcss/typography')],
82 | } satisfies Config
83 |
84 | export default config
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["dom", "dom.iterable", "esnext"],
4 | "allowJs": true,
5 | "skipLibCheck": true,
6 | "strict": true,
7 | "noEmit": true,
8 | "esModuleInterop": true,
9 | "target": "esnext",
10 | "module": "esnext",
11 | "moduleResolution": "node",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "preserve",
15 | "incremental": true,
16 | "types": ["node"],
17 | "plugins": [
18 | {
19 | "name": "next"
20 | }
21 | ],
22 | "paths": {
23 | "@/*": ["./*"],
24 | "@/frontend/*": ["./components/frontend/*"],
25 | }
26 | },
27 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
28 | "exclude": ["node_modules", "bin"]
29 | }
30 |
--------------------------------------------------------------------------------