@jjlmoya/utils-developer 1.14.0 → 1.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/category/i18n/fr.ts +1 -1
- package/src/category/i18n/ru.ts +1 -1
- package/src/category/index.ts +2 -1
- package/src/entries.ts +4 -1
- package/src/index.ts +2 -0
- package/src/layouts/PreviewLayout.astro +1 -0
- package/src/pages/[locale]/[slug].astro +29 -12
- package/src/tests/diacritics_density.test.ts +118 -0
- package/src/tests/inverted_punctuation.test.ts +113 -0
- package/src/tests/locale_completeness.test.ts +2 -3
- package/src/tests/no_en_dash.test.ts +73 -0
- package/src/tests/pagespeed_best_practices.test.ts +198 -0
- package/src/tests/script_density.test.ts +94 -0
- package/src/tests/shared-test-helpers.ts +56 -0
- package/src/tests/tool_exports.test.ts +34 -0
- package/src/tests/tool_validation.test.ts +2 -2
- package/src/tool/aspectRatio/component.astro +3 -1
- package/src/tool/aspectRatio/i18n/de.ts +1 -1
- package/src/tool/aspectRatio/i18n/fr.ts +1 -1
- package/src/tool/aspectRatio/i18n/pl.ts +2 -2
- package/src/tool/aspectRatio/i18n/ru.ts +4 -4
- package/src/tool/aspectRatio/i18n/zh.ts +1 -1
- package/src/tool/aspectRatio/seo.astro +2 -1
- package/src/tool/calculadoraTiempoDatos/i18n/de.ts +1 -1
- package/src/tool/calculadoraTiempoDatos/i18n/pl.ts +1 -1
- package/src/tool/calculadoraTiempoDatos/i18n/ru.ts +5 -5
- package/src/tool/calculadoraTiempoDatos/i18n/sv.ts +5 -5
- package/src/tool/calculadoraTiempoDatos/i18n/zh.ts +1 -1
- package/src/tool/calculadoraTiempoDatos/seo.astro +2 -1
- package/src/tool/colorConverter/component.astro +3 -3
- package/src/tool/colorConverter/i18n/de.ts +1 -1
- package/src/tool/colorConverter/i18n/ru.ts +2 -2
- package/src/tool/colorConverter/seo.astro +2 -1
- package/src/tool/conversorExcelCsvHtml/i18n/es.ts +1 -1
- package/src/tool/conversorExcelCsvHtml/i18n/pl.ts +1 -1
- package/src/tool/conversorExcelCsvHtml/i18n/ru.ts +2 -2
- package/src/tool/conversorExcelCsvHtml/i18n/zh.ts +2 -2
- package/src/tool/conversorExcelCsvHtml/seo.astro +2 -1
- package/src/tool/cronGenerator/i18n/de.ts +4 -4
- package/src/tool/cronGenerator/i18n/en.ts +1 -1
- package/src/tool/cronGenerator/i18n/es.ts +2 -2
- package/src/tool/cronGenerator/i18n/fr.ts +5 -5
- package/src/tool/cronGenerator/i18n/id.ts +1 -1
- package/src/tool/cronGenerator/i18n/nl.ts +1 -1
- package/src/tool/cronGenerator/i18n/pl.ts +8 -8
- package/src/tool/cronGenerator/i18n/pt.ts +1 -1
- package/src/tool/cronGenerator/i18n/ru.ts +9 -9
- package/src/tool/cronGenerator/i18n/sv.ts +1 -1
- package/src/tool/cronGenerator/i18n/zh.ts +3 -3
- package/src/tool/cronGenerator/seo.astro +2 -1
- package/src/tool/cssSpecificityCalculator/i18n/de.ts +1 -1
- package/src/tool/cssSpecificityCalculator/i18n/fr.ts +3 -3
- package/src/tool/cssSpecificityCalculator/i18n/pl.ts +2 -2
- package/src/tool/cssSpecificityCalculator/i18n/ru.ts +2 -2
- package/src/tool/cssSpecificityCalculator/seo.astro +2 -1
- package/src/tool/cssToInlineConverter/i18n/de.ts +6 -6
- package/src/tool/cssToInlineConverter/i18n/es.ts +1 -1
- package/src/tool/cssToInlineConverter/i18n/fr.ts +3 -3
- package/src/tool/cssToInlineConverter/seo.astro +2 -1
- package/src/tool/duplicateCssRemover/i18n/de.ts +7 -7
- package/src/tool/duplicateCssRemover/i18n/fr.ts +1 -1
- package/src/tool/duplicateCssRemover/i18n/id.ts +1 -1
- package/src/tool/duplicateCssRemover/i18n/nl.ts +1 -1
- package/src/tool/duplicateCssRemover/i18n/pl.ts +1 -1
- package/src/tool/duplicateCssRemover/i18n/pt.ts +1 -1
- package/src/tool/duplicateCssRemover/i18n/ru.ts +3 -3
- package/src/tool/duplicateCssRemover/i18n/sv.ts +1 -1
- package/src/tool/duplicateCssRemover/seo.astro +2 -1
- package/src/tool/generadorSecurityTxt/i18n/de.ts +5 -5
- package/src/tool/generadorSecurityTxt/i18n/ru.ts +2 -2
- package/src/tool/generadorSecurityTxt/seo.astro +2 -1
- package/src/tool/hashGenerator/i18n/ru.ts +5 -5
- package/src/tool/hashGenerator/i18n/zh.ts +2 -2
- package/src/tool/hashGenerator/seo.astro +2 -1
- package/src/tool/inspectorCertificadosSsl/i18n/de.ts +6 -6
- package/src/tool/inspectorCertificadosSsl/i18n/ru.ts +5 -5
- package/src/tool/inspectorCertificadosSsl/seo.astro +2 -1
- package/src/tool/jsonFormatter/i18n/de.ts +4 -4
- package/src/tool/jsonFormatter/i18n/en.ts +4 -4
- package/src/tool/jsonFormatter/i18n/es.ts +4 -4
- package/src/tool/jsonFormatter/i18n/fr.ts +4 -4
- package/src/tool/jsonFormatter/i18n/id.ts +4 -4
- package/src/tool/jsonFormatter/i18n/it.ts +4 -4
- package/src/tool/jsonFormatter/i18n/ja.ts +4 -4
- package/src/tool/jsonFormatter/i18n/ko.ts +4 -4
- package/src/tool/jsonFormatter/i18n/nl.ts +4 -4
- package/src/tool/jsonFormatter/i18n/pl.ts +4 -4
- package/src/tool/jsonFormatter/i18n/pt.ts +4 -4
- package/src/tool/jsonFormatter/i18n/ru.ts +5 -5
- package/src/tool/jsonFormatter/i18n/sv.ts +4 -4
- package/src/tool/jsonFormatter/i18n/tr.ts +4 -4
- package/src/tool/jsonFormatter/i18n/zh.ts +5 -5
- package/src/tool/jsonFormatter/seo.astro +2 -1
- package/src/tool/keycode/i18n/de.ts +7 -7
- package/src/tool/keycode/i18n/en.ts +5 -5
- package/src/tool/keycode/i18n/es.ts +5 -5
- package/src/tool/keycode/i18n/fr.ts +7 -7
- package/src/tool/keycode/i18n/id.ts +5 -5
- package/src/tool/keycode/i18n/it.ts +5 -5
- package/src/tool/keycode/i18n/ja.ts +5 -5
- package/src/tool/keycode/i18n/ko.ts +5 -5
- package/src/tool/keycode/i18n/nl.ts +5 -5
- package/src/tool/keycode/i18n/pl.ts +7 -7
- package/src/tool/keycode/i18n/pt.ts +5 -5
- package/src/tool/keycode/i18n/ru.ts +6 -6
- package/src/tool/keycode/i18n/sv.ts +5 -5
- package/src/tool/keycode/i18n/tr.ts +5 -5
- package/src/tool/keycode/i18n/zh.ts +5 -5
- package/src/tool/keycode/seo.astro +2 -1
- package/src/tool/llmCostCalculator/component.astro +1 -2
- package/src/tool/llmCostCalculator/i18n/de.ts +4 -4
- package/src/tool/llmCostCalculator/i18n/en.ts +3 -3
- package/src/tool/llmCostCalculator/i18n/fr.ts +3 -3
- package/src/tool/llmCostCalculator/i18n/id.ts +3 -3
- package/src/tool/llmCostCalculator/i18n/pt.ts +3 -3
- package/src/tool/llmCostCalculator/i18n/ru.ts +3 -3
- package/src/tool/llmCostCalculator/i18n/sv.ts +3 -3
- package/src/tool/llmCostCalculator/i18n/tr.ts +3 -3
- package/src/tool/llmCostCalculator/i18n/zh.ts +3 -3
- package/src/tool/llmCostCalculator/seo.astro +2 -1
- package/src/tool/mobileMockupGenerator/component.astro +4 -5
- package/src/tool/mobileMockupGenerator/i18n/es.ts +1 -1
- package/src/tool/mobileMockupGenerator/seo.astro +2 -1
- package/src/tool/musicalTypography/i18n/de.ts +1 -1
- package/src/tool/musicalTypography/i18n/fr.ts +1 -1
- package/src/tool/musicalTypography/i18n/id.ts +1 -1
- package/src/tool/musicalTypography/i18n/it.ts +1 -1
- package/src/tool/musicalTypography/i18n/ko.ts +1 -1
- package/src/tool/musicalTypography/i18n/ru.ts +3 -3
- package/src/tool/musicalTypography/seo.astro +2 -1
- package/src/tool/placeholderGenerator/component.astro +2 -2
- package/src/tool/placeholderGenerator/i18n/de.ts +4 -4
- package/src/tool/placeholderGenerator/i18n/ru.ts +1 -1
- package/src/tool/placeholderGenerator/seo.astro +2 -1
- package/src/tool/promptLibrary/i18n/de.ts +1 -1
- package/src/tool/promptLibrary/seo.astro +2 -1
- package/src/tool/readabilityCalculator/component.astro +4 -4
- package/src/tool/readabilityCalculator/i18n/de.ts +2 -2
- package/src/tool/readabilityCalculator/seo.astro +2 -1
- package/src/tool/readabilityCalculator/visual-readability-calculator-wcag-apca.css +87 -3
- package/src/tool/serpPixelSimulator/bibliography.astro +7 -0
- package/src/tool/serpPixelSimulator/bibliography.ts +16 -0
- package/src/tool/serpPixelSimulator/component.astro +84 -0
- package/src/tool/serpPixelSimulator/controller.ts +323 -0
- package/src/tool/serpPixelSimulator/entry.ts +30 -0
- package/src/tool/serpPixelSimulator/i18n/de.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/en.ts +213 -0
- package/src/tool/serpPixelSimulator/i18n/es.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/fr.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/id.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/it.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/ja.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/ko.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/nl.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/pl.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/pt.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/ru.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/sv.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/tr.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/zh.ts +214 -0
- package/src/tool/serpPixelSimulator/index.ts +12 -0
- package/src/tool/serpPixelSimulator/logic.ts +18 -0
- package/src/tool/serpPixelSimulator/seo.astro +12 -0
- package/src/tool/serpPixelSimulator/serp-pixel-simulator.css +335 -0
- package/src/tool/serpPixelSimulator/ui.ts +33 -0
- package/src/tool/svgSanitizer/i18n/de.ts +2 -2
- package/src/tool/svgSanitizer/i18n/id.ts +1 -1
- package/src/tool/svgSanitizer/i18n/pl.ts +1 -1
- package/src/tool/svgSanitizer/i18n/ru.ts +7 -7
- package/src/tool/svgSanitizer/i18n/sv.ts +3 -3
- package/src/tool/svgSanitizer/i18n/tr.ts +3 -3
- package/src/tool/svgSanitizer/i18n/zh.ts +3 -3
- package/src/tool/svgSanitizer/seo.astro +2 -1
- package/src/tool/svgToCss/i18n/de.ts +2 -2
- package/src/tool/svgToCss/i18n/es.ts +1 -1
- package/src/tool/svgToCss/i18n/fr.ts +1 -1
- package/src/tool/svgToCss/i18n/pl.ts +1 -1
- package/src/tool/svgToCss/i18n/ru.ts +2 -2
- package/src/tool/svgToCss/i18n/zh.ts +2 -2
- package/src/tool/svgToCss/seo.astro +2 -1
- package/src/tool/urlCleaner/component.astro +23 -5
- package/src/tool/urlCleaner/i18n/de.ts +3 -3
- package/src/tool/urlCleaner/i18n/es.ts +1 -1
- package/src/tool/urlCleaner/i18n/id.ts +1 -1
- package/src/tool/urlCleaner/i18n/nl.ts +1 -1
- package/src/tool/urlCleaner/seo.astro +2 -1
- package/src/tool/urlCleaner/url-tracking-cleaner.css +92 -2
- package/src/tool/urlEncoderDecoder/i18n/de.ts +5 -5
- package/src/tool/urlEncoderDecoder/i18n/fr.ts +2 -2
- package/src/tool/urlEncoderDecoder/i18n/pl.ts +5 -5
- package/src/tool/urlEncoderDecoder/i18n/ru.ts +8 -8
- package/src/tool/urlEncoderDecoder/i18n/sv.ts +5 -5
- package/src/tool/urlEncoderDecoder/i18n/zh.ts +5 -5
- package/src/tool/urlEncoderDecoder/seo.astro +2 -1
- package/src/tool/utmGenerator/i18n/de.ts +2 -2
- package/src/tool/utmGenerator/i18n/pl.ts +5 -5
- package/src/tool/utmGenerator/i18n/ru.ts +6 -6
- package/src/tool/utmGenerator/seo.astro +2 -1
- package/src/tools.ts +2 -2
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import type { SerpPixelSimulatorUI } from '../ui';
|
|
4
|
+
import { bibliography } from '../bibliography';
|
|
5
|
+
|
|
6
|
+
const slug = 'symulator-serp-licznik-pikseli';
|
|
7
|
+
const title = 'Symulator SERP i Licznik Pikseli SEO';
|
|
8
|
+
const description = 'Podglądaj fragmenty wyników wyszukiwania w stylu Google w czasie rzeczywistym, mierz szerokość tytułu i meta opisu w pikselach i zobacz dokładnie, gdzie twój tekst zostanie przycięty.';
|
|
9
|
+
|
|
10
|
+
const howTo = [
|
|
11
|
+
{
|
|
12
|
+
name: 'Wprowadź znacznik title',
|
|
13
|
+
text: 'Wpisz lub wklej tytuł strony, który chcesz przetestować. Podgląd SERP i miernik pikseli aktualizują się przy każdym naciśnięciu klawisza.',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: 'Dodaj widoczny adres URL',
|
|
17
|
+
text: 'Użyj realistycznej domeny i ścieżki, aby fragment przypominał wynik, który przeskanowałby użytkownik.',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: 'Wpisz meta opis',
|
|
21
|
+
text: 'Dodaj tekst opisu i obserwuj pasek pikseli. Gdy przekroczy zalecaną szerokość wizualną, podgląd przycina go wielokropkiem.',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'Przełącz między pulpitem a urządzeniem mobilnym',
|
|
25
|
+
text: 'Porównaj renderowanie tytułu z szerokością karty na pulpicie lub urządzeniu mobilnym przed opublikowaniem metadanych.',
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
const faq = [
|
|
30
|
+
{
|
|
31
|
+
question: 'Dlaczego liczyć piksele zamiast znaków dla tytułów SEO?',
|
|
32
|
+
answer: 'Karty wyników Google są ograniczone szerokością wizualną. Tytuł z wieloma wąskimi literami może pomieścić więcej znaków niż tytuł z szerokimi literami, wielkimi literami lub grubo wyglądającymi glifami. Pomiar w pikselach daje dokładniejszy podgląd widocznego wyniku.',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
question: 'Czy to gwarantuje dokładnie, jak Google przytnie mój fragment?',
|
|
36
|
+
answer: 'Nie. Google może przepisywać linki tytułowe i fragmenty, a renderowanie może się różnić w zależności od zapytania, urządzenia, języka i eksperymentów. Narzędzie jest pomyślane jako praktyczna wizualna wskazówka do pisania metadanych, które rzadziej zostaną przycięte.',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
question: 'Jakie limity pikseli stosuje symulator?',
|
|
40
|
+
answer: 'Domyślny limit tytułu na pulpicie wynosi 580 px, na urządzeniu mobilnym 600 px, a limit meta opisu to 920 px. Są to cele redakcyjne, a nie oficjalne limity Google.',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
question: 'Dlaczego podgląd dodaje wielokropek?',
|
|
44
|
+
answer: 'Gdy zmierzony tekst przekracza dostępną szerokość w pikselach, symulator przycina ciąg przy ostatnim pasującym znaku i dodaje trzy kropki, naśladując praktyczne zachowanie potrzebne zespołom SEO do wykrywania utraty znaczenia.',
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
const ui: SerpPixelSimulatorUI = {
|
|
49
|
+
titleLabel: 'Znacznik title',
|
|
50
|
+
titlePlaceholder: 'GameBob | Niezależne Studio Deweloperskie',
|
|
51
|
+
urlLabel: 'Widoczny URL',
|
|
52
|
+
urlPlaceholder: 'https://www.gamebob.dev/pl/',
|
|
53
|
+
descriptionLabel: 'Meta opis',
|
|
54
|
+
descriptionPlaceholder: 'Odkryj naszą kolekcję narzędzi i gier zaprojektowanych, aby ulepszyć twój cyfrowy przepływ pracy i rozrywkę.',
|
|
55
|
+
deviceLabel: 'Tryb podglądu',
|
|
56
|
+
desktopLabel: 'Pulpit',
|
|
57
|
+
mobileLabel: 'Mobilny',
|
|
58
|
+
titlePixelsLabel: 'Szerokość tytułu',
|
|
59
|
+
descriptionPixelsLabel: 'Szerokość opisu',
|
|
60
|
+
charactersLabel: 'znaków',
|
|
61
|
+
previewLabel: 'Podgląd na żywo w stylu Google',
|
|
62
|
+
tooLongLabel: 'Za szeroki',
|
|
63
|
+
goodLabel: 'Pasuje',
|
|
64
|
+
emptyTitle: 'Twój tytuł pojawi się tutaj',
|
|
65
|
+
emptyDescription: 'Podgląd twojego meta opisu pojawi się tutaj podczas pisania.',
|
|
66
|
+
defaultTitle: 'GameBob | Niezależne Studio Deweloperskie',
|
|
67
|
+
defaultUrl: 'https://www.gamebob.dev/pl/',
|
|
68
|
+
defaultDescription: 'Odkryj naszą kolekcję narzędzi i gier zaprojektowanych, aby ulepszyć twój cyfrowy przepływ pracy i rozrywkę.',
|
|
69
|
+
fallbackUrl: 'przyklad.pl',
|
|
70
|
+
fallbackFaviconText: 'G',
|
|
71
|
+
pixelUnit: 'px',
|
|
72
|
+
ellipsis: '...',
|
|
73
|
+
fetchButtonLabel: 'Pobierz',
|
|
74
|
+
fetchLoadingLabel: 'Pobieranie...',
|
|
75
|
+
fetchSuccessLabel: 'Metadane załadowane z adresu URL.',
|
|
76
|
+
fetchCorsError: 'Przeglądarka nie mogła odczytać tej strony. Może być zablokowana przez CORS, przekierowanie, mieszaną zawartość lub regułę sieciową. Nadal możesz wkleić lub edytować metadane ręcznie.',
|
|
77
|
+
fetchInvalidUrlError: 'Wprowadź prawidłowy adres URL przed pobraniem metadanych.',
|
|
78
|
+
fetchNoMetadataError: 'Strona została pobrana, ale nie znaleziono tytułu ani meta opisu.',
|
|
79
|
+
fetchGenericError: 'Nie można pobrać metadanych z tego adresu URL. Sprawdź adres lub wypełnij pola ręcznie.',
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const faqSchema: WithContext<FAQPage> = {
|
|
83
|
+
'@context': 'https://schema.org',
|
|
84
|
+
'@type': 'FAQPage',
|
|
85
|
+
mainEntity: faq.map((item) => ({
|
|
86
|
+
'@type': 'Question',
|
|
87
|
+
name: item.question,
|
|
88
|
+
acceptedAnswer: {
|
|
89
|
+
'@type': 'Answer',
|
|
90
|
+
text: item.answer,
|
|
91
|
+
},
|
|
92
|
+
})),
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const howToSchema: WithContext<HowTo> = {
|
|
96
|
+
'@context': 'https://schema.org',
|
|
97
|
+
'@type': 'HowTo',
|
|
98
|
+
name: title,
|
|
99
|
+
description,
|
|
100
|
+
step: howTo.map((step, index) => ({
|
|
101
|
+
'@type': 'HowToStep',
|
|
102
|
+
position: index + 1,
|
|
103
|
+
name: step.name,
|
|
104
|
+
text: step.text,
|
|
105
|
+
})),
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const appSchema: WithContext<SoftwareApplication> = {
|
|
109
|
+
'@context': 'https://schema.org',
|
|
110
|
+
'@type': 'SoftwareApplication',
|
|
111
|
+
name: title,
|
|
112
|
+
description,
|
|
113
|
+
applicationCategory: 'BusinessApplication',
|
|
114
|
+
operatingSystem: 'Any',
|
|
115
|
+
offers: {
|
|
116
|
+
'@type': 'Offer',
|
|
117
|
+
price: '0',
|
|
118
|
+
priceCurrency: 'EUR',
|
|
119
|
+
},
|
|
120
|
+
inLanguage: 'pl',
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export const content: ToolLocaleContent<SerpPixelSimulatorUI> = {
|
|
124
|
+
slug,
|
|
125
|
+
title,
|
|
126
|
+
description,
|
|
127
|
+
ui,
|
|
128
|
+
faqTitle: 'Najczęściej zadawane pytania o symulator SERP',
|
|
129
|
+
faq,
|
|
130
|
+
bibliographyTitle: 'Dokumentacja dotycząca wyników wyszukiwania',
|
|
131
|
+
bibliography,
|
|
132
|
+
howTo,
|
|
133
|
+
schemas: [appSchema, faqSchema, howToSchema],
|
|
134
|
+
seo: [
|
|
135
|
+
{
|
|
136
|
+
type: 'title',
|
|
137
|
+
text: 'Przestań zgadywać, jak będzie wyglądać twój wynik w Google',
|
|
138
|
+
level: 2,
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
type: 'paragraph',
|
|
142
|
+
html: 'Znacznik title może wyglądać idealnie w arkuszu kalkulacyjnym, a mimo to zawieść w wyniku wyszukiwania. Google nie rezerwuje miejsca według liczby znaków; renderuje tekst wewnątrz karty wizualnej. Oznacza to, że <strong>GameBob | Niezależne Studio Deweloperskie</strong> i inny tytuł o tej samej liczbie znaków mogą zajmować bardzo różne szerokości w zależności od liter, wielkości znaków, interpunkcji i odstępów.',
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
type: 'tip',
|
|
146
|
+
title: 'Zasada, która naprawdę pomaga',
|
|
147
|
+
html: 'Napisz fragment tak, aby ważna obietnica przetrwała wielokropek. Umieść typ strony, intencję wyszukiwania i najsilniejszy powód do kliknięcia przed limitem pikseli. Nazwy marek są przydatne, ale nie powinny wypychać głównej korzyści poza widok.',
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
type: 'title',
|
|
151
|
+
text: 'Co mierzy licznik pikseli',
|
|
152
|
+
level: 3,
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
type: 'table',
|
|
156
|
+
headers: ['Element', 'Co ma znaczenie', 'Jak użyć wyniku'],
|
|
157
|
+
rows: [
|
|
158
|
+
['Znacznik title', 'Szerokość renderowana w pikselach, nie surowa liczba znaków', 'Utrzymuj główne słowo kluczowe i obietnicę kliknięcia widoczne przed przycięciem.'],
|
|
159
|
+
['Widoczny URL', 'Zaufanie wizualne i jasność tematu', 'Użyj czytelnej ścieżki, która wzmacnia, dokąd prowadzi wynik.'],
|
|
160
|
+
['Meta opis', 'Szerszy obszar fragmentu z zachowaniem zależnym od zapytania', 'Umieść korzyść na początku, ponieważ Google może go skrócić lub przepisać.'],
|
|
161
|
+
['Tryb urządzenia', 'Karty na pulpicie i urządzeniach mobilnych mogą wyglądać inaczej', 'Sprawdź oba przed opublikowaniem metadanych dla ważnych stron.'],
|
|
162
|
+
],
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
type: 'title',
|
|
166
|
+
text: 'Dlaczego limity znaków to słaby nawyk SEO',
|
|
167
|
+
level: 3,
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
type: 'paragraph',
|
|
171
|
+
html: 'Tradycyjna porada, taka jak "utrzymuj tytuły poniżej 60 znaków", jest wygodna, ale ukrywa prawdziwy problem. Szerokie litery, takie jak W i M, wielkie litery, separatory, cyfry i długie nazwy marek zajmują różną przestrzeń. Pomiar w pikselach natychmiast uwidacznia kompromis: możesz zobaczyć, czy fraza zasługuje na swoje miejsce, czy kradnie przestrzeń silniejszemu przekazowi.',
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
type: 'title',
|
|
175
|
+
text: 'Praktyczny przepływ pracy dla lepszych fragmentów',
|
|
176
|
+
level: 3,
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
type: 'list',
|
|
180
|
+
items: [
|
|
181
|
+
'<strong>Zacznij od intencji:</strong> opisz, co otrzymuje użytkownik, a nie tylko jak nazywa się strona.',
|
|
182
|
+
'<strong>Przetestuj pełny tytuł:</strong> wklej go do symulatora i obserwuj pasek przed publikacją.',
|
|
183
|
+
'<strong>Usuń słabe słowa:</strong> jeśli pasek zmieni kolor na czerwony, usuń wypełniacze przed obcięciem wartościowych terminów.',
|
|
184
|
+
'<strong>Sprawdź wielokropek:</strong> jeśli przycięty podgląd traci znaczenie, przepisz tytuł zamiast akceptować cięcie.',
|
|
185
|
+
'<strong>Powtórz dla opisu:</strong> upewnij się, że pierwsze zdanie samodzielnie niesie propozycję wartości.',
|
|
186
|
+
],
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
type: 'diagnostic',
|
|
190
|
+
variant: 'info',
|
|
191
|
+
title: 'Gdy pasek zmienia kolor na czerwony',
|
|
192
|
+
html: 'Czerwony pasek nie jest ostrzeżeniem o karze. Oznacza, że bieżący tekst jest szerszy niż wybrany cel wizualny, więc symulator przycina go kropkami. Potraktuj to jako sygnał redakcyjny: zdecyduj, czy ukryte słowa są zbędne, czy fragment potrzebuje ostrzejszej struktury.',
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
type: 'title',
|
|
196
|
+
text: 'Ograniczenia, przepisywanie i realistyczne oczekiwania',
|
|
197
|
+
level: 3,
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
type: 'paragraph',
|
|
201
|
+
html: 'Żaden symulator nie może zagwarantować dokładnego fragmentu, który pokaże Google. Google może przepisywać linki tytułowe, pogrubiać terminy zapytania, wybierać tekst strony zamiast meta opisu lub wyświetlać różne fragmenty dla różnych wyszukiwań. To narzędzie najlepiej sprawdza się jako szybki etap redakcyjny i kontroli jakości: wykrywa oczywiste przepełnienia wizualne, zanim strona trafi do produkcji.',
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
type: 'summary',
|
|
205
|
+
title: 'Najlepsze wykorzystanie tego symulatora SERP',
|
|
206
|
+
items: [
|
|
207
|
+
'Użyj paska pikseli, aby wykryć przepełnienia wizualne przed opublikowaniem metadanych.',
|
|
208
|
+
'Utrzymuj główną intencję wyszukiwania i obietnicę kliknięcia widoczne przed jakimkolwiek wielokropkiem.',
|
|
209
|
+
'Pobieraj metadane z adresów URL, które zezwalają na CORS, a następnie edytuj wynik ręcznie w razie potrzeby.',
|
|
210
|
+
'Traktuj podgląd jako wskazówkę redakcyjną, ponieważ Google wciąż może przepisywać fragmenty w zależności od zapytania.',
|
|
211
|
+
],
|
|
212
|
+
},
|
|
213
|
+
],
|
|
214
|
+
};
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import type { SerpPixelSimulatorUI } from '../ui';
|
|
4
|
+
import { bibliography } from '../bibliography';
|
|
5
|
+
|
|
6
|
+
const slug = 'simulador-serp-contador-pixels';
|
|
7
|
+
const title = 'Simulador SERP e Contador de Píxeis SEO';
|
|
8
|
+
const description = 'Pré-visualize snippets de pesquisa ao estilo Google em tempo real, meça a largura em píxeis do título e da meta description e veja exatamente onde o seu texto será truncado.';
|
|
9
|
+
|
|
10
|
+
const howTo = [
|
|
11
|
+
{
|
|
12
|
+
name: 'Introduza a tag title',
|
|
13
|
+
text: 'Digite ou cole o título da página que pretende testar. A pré-visualização SERP e o medidor de píxeis atualizam-se a cada tecla premida.',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: 'Adicione o URL visível',
|
|
17
|
+
text: 'Use um domínio e caminho realistas para que o snippet se pareça com o resultado que um utilizador analisaria.',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: 'Escreva a meta description',
|
|
21
|
+
text: 'Adicione o texto da descrição e observe a barra de píxeis. Quando excede a largura visual recomendada, a pré-visualização trunca-a com reticências.',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'Alterne entre desktop e mobile',
|
|
25
|
+
text: 'Compare a renderização do título com a largura do cartão de desktop ou mobile antes de publicar os metadados.',
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
const faq = [
|
|
30
|
+
{
|
|
31
|
+
question: 'Porquê contar píxeis em vez de caracteres para títulos SEO?',
|
|
32
|
+
answer: 'Os cartões de resultados do Google são limitados pela largura visual. Um título com muitas letras estreitas pode conter mais caracteres do que um com letras largas, maiúsculas ou glifos de aspeto espesso. A medição em píxeis oferece uma pré-visualização mais fiel do resultado visível.',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
question: 'Isto garante exatamente como o Google irá truncar o meu snippet?',
|
|
36
|
+
answer: 'Não. O Google pode reescrever os links de título e os snippets, e a renderização pode variar consoante a consulta, o dispositivo, o idioma e as experiências. A ferramenta foi concebida como um guia visual prático para escrever metadados com menor probabilidade de serem cortados.',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
question: 'Que limites de píxeis utiliza o simulador?',
|
|
40
|
+
answer: 'O limite predefinido do título em desktop é de 580 px, o do título em mobile é de 600 px e o limite da meta description é de 920 px. São metas de redação, não limites oficiais do Google.',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
question: 'Porque é que a pré-visualização adiciona reticências?',
|
|
44
|
+
answer: 'Quando o texto medido excede a largura de píxeis disponível, o simulador trunca a string no último caractere que cabe e acrescenta três pontos, reproduzindo o comportamento prático de que as equipas de SEO precisam para detetar perda de significado.',
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
const ui: SerpPixelSimulatorUI = {
|
|
49
|
+
titleLabel: 'Tag title',
|
|
50
|
+
titlePlaceholder: 'GameBob | Estúdio de Desenvolvimento Independente',
|
|
51
|
+
urlLabel: 'URL visível',
|
|
52
|
+
urlPlaceholder: 'https://www.gamebob.dev/pt/',
|
|
53
|
+
descriptionLabel: 'Meta description',
|
|
54
|
+
descriptionPlaceholder: 'Descubra a nossa coleção de ferramentas e jogos concebidos para elevar o seu fluxo de trabalho digital e entretenimento.',
|
|
55
|
+
deviceLabel: 'Modo de pré-visualização',
|
|
56
|
+
desktopLabel: 'Desktop',
|
|
57
|
+
mobileLabel: 'Mobile',
|
|
58
|
+
titlePixelsLabel: 'Largura do título',
|
|
59
|
+
descriptionPixelsLabel: 'Largura da descrição',
|
|
60
|
+
charactersLabel: 'caracteres',
|
|
61
|
+
previewLabel: 'Pré-visualização ao vivo estilo Google',
|
|
62
|
+
tooLongLabel: 'Demasiado largo',
|
|
63
|
+
goodLabel: 'Ok',
|
|
64
|
+
emptyTitle: 'O seu título aparecerá aqui',
|
|
65
|
+
emptyDescription: 'A pré-visualização da sua meta description aparecerá aqui enquanto digita.',
|
|
66
|
+
defaultTitle: 'GameBob | Estúdio de Desenvolvimento Independente',
|
|
67
|
+
defaultUrl: 'https://www.gamebob.dev/pt/',
|
|
68
|
+
defaultDescription: 'Descubra a nossa coleção de ferramentas e jogos concebidos para elevar o seu fluxo de trabalho digital e entretenimento.',
|
|
69
|
+
fallbackUrl: 'exemplo.com',
|
|
70
|
+
fallbackFaviconText: 'G',
|
|
71
|
+
pixelUnit: 'px',
|
|
72
|
+
ellipsis: '...',
|
|
73
|
+
fetchButtonLabel: 'Obter',
|
|
74
|
+
fetchLoadingLabel: 'A obter...',
|
|
75
|
+
fetchSuccessLabel: 'Metadados carregados a partir do URL.',
|
|
76
|
+
fetchCorsError: 'O navegador não conseguiu ler esta página. Pode estar bloqueada por CORS, um redireccionamento, conteúdo misto ou uma regra de rede. Pode colar ou editar os metadados manualmente.',
|
|
77
|
+
fetchInvalidUrlError: 'Introduza um URL válido antes de obter os metadados.',
|
|
78
|
+
fetchNoMetadataError: 'A página foi obtida, mas não foi encontrado título nem meta description.',
|
|
79
|
+
fetchGenericError: 'Não foi possível obter os metadados deste URL. Verifique o endereço ou preencha os campos manualmente.',
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const faqSchema: WithContext<FAQPage> = {
|
|
83
|
+
'@context': 'https://schema.org',
|
|
84
|
+
'@type': 'FAQPage',
|
|
85
|
+
mainEntity: faq.map((item) => ({
|
|
86
|
+
'@type': 'Question',
|
|
87
|
+
name: item.question,
|
|
88
|
+
acceptedAnswer: {
|
|
89
|
+
'@type': 'Answer',
|
|
90
|
+
text: item.answer,
|
|
91
|
+
},
|
|
92
|
+
})),
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const howToSchema: WithContext<HowTo> = {
|
|
96
|
+
'@context': 'https://schema.org',
|
|
97
|
+
'@type': 'HowTo',
|
|
98
|
+
name: title,
|
|
99
|
+
description,
|
|
100
|
+
step: howTo.map((step, index) => ({
|
|
101
|
+
'@type': 'HowToStep',
|
|
102
|
+
position: index + 1,
|
|
103
|
+
name: step.name,
|
|
104
|
+
text: step.text,
|
|
105
|
+
})),
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const appSchema: WithContext<SoftwareApplication> = {
|
|
109
|
+
'@context': 'https://schema.org',
|
|
110
|
+
'@type': 'SoftwareApplication',
|
|
111
|
+
name: title,
|
|
112
|
+
description,
|
|
113
|
+
applicationCategory: 'BusinessApplication',
|
|
114
|
+
operatingSystem: 'Any',
|
|
115
|
+
offers: {
|
|
116
|
+
'@type': 'Offer',
|
|
117
|
+
price: '0',
|
|
118
|
+
priceCurrency: 'EUR',
|
|
119
|
+
},
|
|
120
|
+
inLanguage: 'pt',
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export const content: ToolLocaleContent<SerpPixelSimulatorUI> = {
|
|
124
|
+
slug,
|
|
125
|
+
title,
|
|
126
|
+
description,
|
|
127
|
+
ui,
|
|
128
|
+
faqTitle: 'Perguntas frequentes sobre o simulador SERP',
|
|
129
|
+
faq,
|
|
130
|
+
bibliographyTitle: 'Documentação sobre resultados de pesquisa',
|
|
131
|
+
bibliography,
|
|
132
|
+
howTo,
|
|
133
|
+
schemas: [appSchema, faqSchema, howToSchema],
|
|
134
|
+
seo: [
|
|
135
|
+
{
|
|
136
|
+
type: 'title',
|
|
137
|
+
text: 'Deixe de adivinhar como será o seu resultado no Google',
|
|
138
|
+
level: 2,
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
type: 'paragraph',
|
|
142
|
+
html: 'Uma tag title pode parecer perfeita numa folha de cálculo e mesmo assim falhar no resultado de pesquisa. O Google não reserva espaço por contagem de caracteres; renderiza o texto dentro de um cartão visual. Isso significa que <strong>GameBob | Estúdio de Desenvolvimento Independente</strong> e outro título com o mesmo número de caracteres podem ocupar larguras muito diferentes consoante as letras, maiúsculas, pontuação e espaçamento.',
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
type: 'tip',
|
|
146
|
+
title: 'A regra que realmente ajuda',
|
|
147
|
+
html: 'Escreva o snippet para que a promessa importante sobreviva às reticências. Coloque o tipo de página, a intenção de pesquisa e o motivo mais forte para clicar antes do limite de píxeis. Os nomes de marca são úteis, mas não devem empurrar o benefício principal para fora de vista.',
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
type: 'title',
|
|
151
|
+
text: 'O que o contador de píxeis está a medir',
|
|
152
|
+
level: 3,
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
type: 'table',
|
|
156
|
+
headers: ['Elemento', 'O que importa', 'Como usar o resultado'],
|
|
157
|
+
rows: [
|
|
158
|
+
['Tag title', 'Largura renderizada em píxeis, não a contagem bruta de caracteres', 'Mantenha a palavra-chave principal e a promessa de clique visíveis antes do truncamento.'],
|
|
159
|
+
['URL visível', 'Confiança visual e clareza do tópico', 'Use um caminho legível que reforce o destino do resultado.'],
|
|
160
|
+
['Meta description', 'Uma área de snippet mais ampla com comportamento dependente da consulta', 'Coloque o benefício em primeiro plano, pois o Google pode encurtá-la ou reescrevê-la.'],
|
|
161
|
+
['Modo dispositivo', 'Os cartões de desktop e mobile podem parecer diferentes', 'Verifique ambos antes de publicar metadados de páginas importantes.'],
|
|
162
|
+
],
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
type: 'title',
|
|
166
|
+
text: 'Porque é que os limites de caracteres são um mau hábito de SEO',
|
|
167
|
+
level: 3,
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
type: 'paragraph',
|
|
171
|
+
html: 'O conselho tradicional como "mantenha os títulos abaixo dos 60 caracteres" é conveniente, mas esconde o verdadeiro problema. Letras largas como W e M, palavras em maiúsculas, separadores, números e nomes de marca longos consomem todos espaços diferentes. A medição em píxeis torna o compromisso visível de imediato: pode ver se uma frase merece o seu lugar ou rouba espaço a uma mensagem mais forte.',
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
type: 'title',
|
|
175
|
+
text: 'Um fluxo de trabalho prático para melhores snippets',
|
|
176
|
+
level: 3,
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
type: 'list',
|
|
180
|
+
items: [
|
|
181
|
+
'<strong>Comece pela intenção:</strong> descreva o que o utilizador obtém, não apenas como a página se chama.',
|
|
182
|
+
'<strong>Teste o título completo:</strong> cole-o no simulador e observe a barra antes de publicar.',
|
|
183
|
+
'<strong>Remova palavras fracas:</strong> se a barra ficar vermelha, elimine o enchimento antes de cortar termos valiosos.',
|
|
184
|
+
'<strong>Verifique as reticências:</strong> se a pré-visualização truncada perder sentido, reescreva o título em vez de aceitar o corte.',
|
|
185
|
+
'<strong>Repita para a descrição:</strong> certifique-se de que a primeira frase transmite a proposta de valor por si só.',
|
|
186
|
+
],
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
type: 'diagnostic',
|
|
190
|
+
variant: 'info',
|
|
191
|
+
title: 'Quando a barra fica vermelha',
|
|
192
|
+
html: 'Uma barra vermelha não é um aviso de penalização. Significa que o texto atual é mais largo do que o alvo visual selecionado, pelo que o simulador o trunca com pontos. Trate isso como um sinal editorial: decida se as palavras ocultas são dispensáveis ou se o snippet precisa de uma estrutura mais afiada.',
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
type: 'title',
|
|
196
|
+
text: 'Limites, reescritas e expectativas realistas',
|
|
197
|
+
level: 3,
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
type: 'paragraph',
|
|
201
|
+
html: 'Nenhum simulador pode garantir o snippet exato que o Google mostrará. O Google pode reescrever links de título, colocar termos da consulta em negrito, escolher texto da página em vez da meta description ou mostrar snippets diferentes para pesquisas diferentes. Esta ferramenta é mais útil como uma etapa rápida de redação e controlo de qualidade: deteta transbordos visuais óbvios antes de a página chegar à produção.',
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
type: 'summary',
|
|
205
|
+
title: 'Melhor utilização deste simulador SERP',
|
|
206
|
+
items: [
|
|
207
|
+
'Use a barra de píxeis para detetar transbordos visuais antes de publicar metadados.',
|
|
208
|
+
'Mantenha a intenção de pesquisa principal e a promessa de clique visíveis antes de qualquer reticência.',
|
|
209
|
+
'Obtenha metadados de URLs que permitam CORS e edite o resultado manualmente quando necessário.',
|
|
210
|
+
'Considere a pré-visualização como um guia de redação, pois o Google ainda pode reescrever snippets por consulta.',
|
|
211
|
+
],
|
|
212
|
+
},
|
|
213
|
+
],
|
|
214
|
+
};
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import type { SerpPixelSimulatorUI } from '../ui';
|
|
4
|
+
import { bibliography } from '../bibliography';
|
|
5
|
+
|
|
6
|
+
const slug = 'simulyator-serp-schetchik-pikselej';
|
|
7
|
+
const title = 'Симулятор SERP и Счётчик Пикселей для SEO';
|
|
8
|
+
const description = 'Предпросматривайте поисковые сниппеты в стиле Google в реальном времени, измеряйте ширину заголовка и мета-описания в пикселях и точно видите, где ваш текст будет обрезан.';
|
|
9
|
+
|
|
10
|
+
const howTo = [
|
|
11
|
+
{
|
|
12
|
+
name: 'Введите тег title',
|
|
13
|
+
text: 'Введите или вставьте заголовок страницы, который хотите протестировать. Предпросмотр SERP и счётчик пикселей обновляются при каждом нажатии клавиши.',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: 'Добавьте видимый URL',
|
|
17
|
+
text: 'Используйте реалистичный домен и путь, чтобы сниппет был похож на результат, который просканирует пользователь.',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: 'Напишите мета-описание',
|
|
21
|
+
text: 'Добавьте текст описания и следите за полосой пикселей. Когда она превышает рекомендуемую визуальную ширину, предпросмотр обрезает её многоточием.',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'Переключайтесь между компьютером и мобильным',
|
|
25
|
+
text: 'Сравните отображение заголовка с шириной карточки на компьютере или мобильном устройстве перед публикацией метаданных.',
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
const faq = [
|
|
30
|
+
{
|
|
31
|
+
question: 'Почему считать пиксели, а не символы для SEO-заголовков?',
|
|
32
|
+
answer: 'Карточки результатов Google ограничены визуальной шириной. Заголовок с большим количеством узких букв может вместить больше символов, чем заголовок с широкими буквами, прописными или жирно выглядящими глифами. Измерение в пикселях даёт более точное представление о видимом результате.',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
question: 'Гарантирует ли это, как именно Google обрежет мой сниппет?',
|
|
36
|
+
answer: 'Нет. Google может переписывать ссылки заголовков и сниппеты, а отображение может варьироваться в зависимости от запроса, устройства, языка и экспериментов. Инструмент задуман как практическое визуальное руководство для написания метаданных, которые с меньшей вероятностью будут обрезаны.',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
question: 'Какие лимиты пикселей использует симулятор?',
|
|
40
|
+
answer: 'Лимит заголовка по умолчанию для компьютера составляет 580 пикселей, для мобильных - 600 пикселей, а лимит мета-описания - 920 пикселей. Это цели написания, а не официальные лимиты Google.',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
question: 'Почему предпросмотр добавляет многоточие?',
|
|
44
|
+
answer: 'Когда измеренный текст превышает доступную ширину в пикселях, симулятор обрезает строку по последнему вмещающемуся символу и добавляет три точки, имитируя практическое поведение, необходимое SEO-командам для обнаружения потери смысла.',
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
const ui: SerpPixelSimulatorUI = {
|
|
49
|
+
titleLabel: 'Тег title',
|
|
50
|
+
titlePlaceholder: 'GameBob | Независимая Студия Разработки',
|
|
51
|
+
urlLabel: 'Видимый URL',
|
|
52
|
+
urlPlaceholder: 'https://www.gamebob.dev/ru/',
|
|
53
|
+
descriptionLabel: 'Мета-описание',
|
|
54
|
+
descriptionPlaceholder: 'Откройте для себя нашу коллекцию инструментов и игр, созданных для улучшения вашего цифрового рабочего процесса и развлечений.',
|
|
55
|
+
deviceLabel: 'Режим предпросмотра',
|
|
56
|
+
desktopLabel: 'Компьютер',
|
|
57
|
+
mobileLabel: 'Мобильный',
|
|
58
|
+
titlePixelsLabel: 'Ширина заголовка',
|
|
59
|
+
descriptionPixelsLabel: 'Ширина описания',
|
|
60
|
+
charactersLabel: 'символов',
|
|
61
|
+
previewLabel: 'Предпросмотр в стиле Google',
|
|
62
|
+
tooLongLabel: 'Слишком широкий',
|
|
63
|
+
goodLabel: 'Помещается',
|
|
64
|
+
emptyTitle: 'Ваш заголовок появится здесь',
|
|
65
|
+
emptyDescription: 'Предпросмотр вашего мета-описания появится здесь по мере ввода.',
|
|
66
|
+
defaultTitle: 'GameBob | Независимая Студия Разработки',
|
|
67
|
+
defaultUrl: 'https://www.gamebob.dev/ru/',
|
|
68
|
+
defaultDescription: 'Откройте для себя нашу коллекцию инструментов и игр, созданных для улучшения вашего цифрового рабочего процесса и развлечений.',
|
|
69
|
+
fallbackUrl: 'пример.рф',
|
|
70
|
+
fallbackFaviconText: 'G',
|
|
71
|
+
pixelUnit: 'px',
|
|
72
|
+
ellipsis: '...',
|
|
73
|
+
fetchButtonLabel: 'Загрузить',
|
|
74
|
+
fetchLoadingLabel: 'Загрузка...',
|
|
75
|
+
fetchSuccessLabel: 'Метаданные загружены с URL.',
|
|
76
|
+
fetchCorsError: 'Браузер не смог прочитать эту страницу. Возможно, она заблокирована CORS, перенаправлением, смешанным содержимым или сетевым правилом. Вы всё ещё можете вставить или отредактировать метаданные вручную.',
|
|
77
|
+
fetchInvalidUrlError: 'Введите корректный URL перед загрузкой метаданных.',
|
|
78
|
+
fetchNoMetadataError: 'Страница загружена, но заголовок или мета-описание не найдены.',
|
|
79
|
+
fetchGenericError: 'Не удалось загрузить метаданные с этого URL. Проверьте адрес или заполните поля вручную.',
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const faqSchema: WithContext<FAQPage> = {
|
|
83
|
+
'@context': 'https://schema.org',
|
|
84
|
+
'@type': 'FAQPage',
|
|
85
|
+
mainEntity: faq.map((item) => ({
|
|
86
|
+
'@type': 'Question',
|
|
87
|
+
name: item.question,
|
|
88
|
+
acceptedAnswer: {
|
|
89
|
+
'@type': 'Answer',
|
|
90
|
+
text: item.answer,
|
|
91
|
+
},
|
|
92
|
+
})),
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const howToSchema: WithContext<HowTo> = {
|
|
96
|
+
'@context': 'https://schema.org',
|
|
97
|
+
'@type': 'HowTo',
|
|
98
|
+
name: title,
|
|
99
|
+
description,
|
|
100
|
+
step: howTo.map((step, index) => ({
|
|
101
|
+
'@type': 'HowToStep',
|
|
102
|
+
position: index + 1,
|
|
103
|
+
name: step.name,
|
|
104
|
+
text: step.text,
|
|
105
|
+
})),
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const appSchema: WithContext<SoftwareApplication> = {
|
|
109
|
+
'@context': 'https://schema.org',
|
|
110
|
+
'@type': 'SoftwareApplication',
|
|
111
|
+
name: title,
|
|
112
|
+
description,
|
|
113
|
+
applicationCategory: 'BusinessApplication',
|
|
114
|
+
operatingSystem: 'Any',
|
|
115
|
+
offers: {
|
|
116
|
+
'@type': 'Offer',
|
|
117
|
+
price: '0',
|
|
118
|
+
priceCurrency: 'EUR',
|
|
119
|
+
},
|
|
120
|
+
inLanguage: 'ru',
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export const content: ToolLocaleContent<SerpPixelSimulatorUI> = {
|
|
124
|
+
slug,
|
|
125
|
+
title,
|
|
126
|
+
description,
|
|
127
|
+
ui,
|
|
128
|
+
faqTitle: 'Часто задаваемые вопросы о симуляторе SERP',
|
|
129
|
+
faq,
|
|
130
|
+
bibliographyTitle: 'Документация по поисковым результатам',
|
|
131
|
+
bibliography,
|
|
132
|
+
howTo,
|
|
133
|
+
schemas: [appSchema, faqSchema, howToSchema],
|
|
134
|
+
seo: [
|
|
135
|
+
{
|
|
136
|
+
type: 'title',
|
|
137
|
+
text: 'Перестаньте гадать, как будет выглядеть ваш результат в Google',
|
|
138
|
+
level: 2,
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
type: 'paragraph',
|
|
142
|
+
html: 'Тег title может выглядеть идеально в таблице и всё равно провалиться в поисковой выдаче. Google резервирует пространство не по количеству символов; он отображает текст внутри визуальной карточки. Это означает, что <strong>GameBob | Независимая Студия Разработки</strong> и другой заголовок с тем же количеством символов могут занимать очень разную ширину в зависимости от букв, регистра, пунктуации и пробелов.',
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
type: 'tip',
|
|
146
|
+
title: 'Правило, которое действительно помогает',
|
|
147
|
+
html: 'Пишите сниппет так, чтобы важное обещание пережило многоточие. Разместите тип страницы, поисковое намерение и самую сильную причину кликнуть до пиксельного лимита. Названия брендов полезны, но они не должны вытеснять главное преимущество из поля зрения.',
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
type: 'title',
|
|
151
|
+
text: 'Что измеряет счётчик пикселей',
|
|
152
|
+
level: 3,
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
type: 'table',
|
|
156
|
+
headers: ['Элемент', 'Что важно', 'Как использовать результат'],
|
|
157
|
+
rows: [
|
|
158
|
+
['Тег title', 'Отображаемая ширина в пикселях, а не количество символов', 'Держите основное ключевое слово и обещание клика видимыми до обрезки.'],
|
|
159
|
+
['Видимый URL', 'Визуальное доверие и ясность темы', 'Используйте читаемый путь, который подкрепляет, куда ведёт результат.'],
|
|
160
|
+
['Мета-описание', 'Более широкая область сниппета с поведением, зависящим от запроса', 'Выносите преимущество вперёд, поскольку Google может сократить или переписать его.'],
|
|
161
|
+
['Режим устройства', 'Карточки на компьютере и мобильном могут выглядеть по-разному', 'Проверьте оба режима перед публикацией метаданных для важных страниц.'],
|
|
162
|
+
],
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
type: 'title',
|
|
166
|
+
text: 'Почему ограничения по символам - плохая SEO-привычка',
|
|
167
|
+
level: 3,
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
type: 'paragraph',
|
|
171
|
+
html: 'Традиционный совет вроде "держите заголовки до 60 символов" удобен, но скрывает реальную проблему. Широкие буквы, такие как W и M, заглавные буквы, разделители, цифры и длинные названия брендов занимают разное пространство. Измерение в пикселях немедленно делает компромисс видимым: вы можете увидеть, заслуживает ли фраза своего места или крадёт пространство у более сильного сообщения.',
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
type: 'title',
|
|
175
|
+
text: 'Практический рабочий процесс для лучших сниппетов',
|
|
176
|
+
level: 3,
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
type: 'list',
|
|
180
|
+
items: [
|
|
181
|
+
'<strong>Начните с намерения:</strong> опишите, что получает пользователь, а не только как называется страница.',
|
|
182
|
+
'<strong>Протестируйте полный заголовок:</strong> вставьте его в симулятор и следите за полосой перед публикацией.',
|
|
183
|
+
'<strong>Уберите слабые слова:</strong> если полоса стала красной, удалите наполнители, прежде чем обрезать ценные термины.',
|
|
184
|
+
'<strong>Проверьте многоточие:</strong> если обрезанный предпросмотр теряет смысл, перепишите заголовок, а не принимайте обрезку.',
|
|
185
|
+
'<strong>Повторите для описания:</strong> убедитесь, что первое предложение само по себе несёт ценностное предложение.',
|
|
186
|
+
],
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
type: 'diagnostic',
|
|
190
|
+
variant: 'info',
|
|
191
|
+
title: 'Когда полоса становится красной',
|
|
192
|
+
html: 'Красная полоса не является предупреждением о штрафе. Она означает, что текущий текст шире выбранной визуальной цели, поэтому симулятор обрезает его точками. Относитесь к этому как к редакционному сигналу: решите, можно ли пожертвовать скрытыми словами, или сниппет нуждается в более чёткой структуре.',
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
type: 'title',
|
|
196
|
+
text: 'Ограничения, переписывания и реалистичные ожидания',
|
|
197
|
+
level: 3,
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
type: 'paragraph',
|
|
201
|
+
html: 'Ни один симулятор не может гарантировать точный сниппет, который покажет Google. Google может переписывать ссылки заголовков, выделять жирным термины запроса, выбирать текст страницы вместо мета-описания или показывать разные сниппеты для разных поисковых запросов. Этот инструмент лучше всего использовать как быстрый этап написания и контроля качества: он выявляет явные визуальные переполнения до того, как страница попадёт в продакшн.',
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
type: 'summary',
|
|
205
|
+
title: 'Наилучшее использование этого симулятора SERP',
|
|
206
|
+
items: [
|
|
207
|
+
'Используйте полосу пикселей для обнаружения визуальных переполнений перед публикацией метаданных.',
|
|
208
|
+
'Держите основное поисковое намерение и обещание клика видимыми до любого многоточия.',
|
|
209
|
+
'Загружайте метаданные с URL, которые разрешают CORS, затем редактируйте результат вручную при необходимости.',
|
|
210
|
+
'Рассматривайте предпросмотр как руководство по написанию, поскольку Google всё ещё может переписывать сниппеты под каждый запрос.',
|
|
211
|
+
],
|
|
212
|
+
},
|
|
213
|
+
],
|
|
214
|
+
};
|