feat: update brand name, add domain

This commit is contained in:
2026-10-12 06:03:55 +05:00
parent 5a7f598d50
commit b7ba1f501f
28 changed files with 96 additions and 113 deletions
@@ -22,7 +22,7 @@ const ruleTester = new RuleTester({
},
});
const OPTIONS = [{ allowWords: ["easy-png-tools"] }];
const OPTIONS = [{ allowWords: ["easy-image-tools"] }];
ruleTester.run("no-hardcoded-user-text", asRuleModule(rule), {
valid: [
@@ -62,12 +62,12 @@ ruleTester.run("no-hardcoded-user-text", asRuleModule(rule), {
},
// Brand configured as an allowed word.
{
code: "<span>easy-png-tools</span>",
code: "<span>easy-image-tools</span>",
filename: "Component.svelte",
options: OPTIONS,
},
{
code: "<footer><span>easy-png-tools</span><span>v0.1.0</span></footer>",
code: "<footer><span>easy-image-tools</span><span>v0.1.0</span></footer>",
filename: "Component.svelte",
options: OPTIONS,
},
@@ -130,7 +130,7 @@ ruleTester.run("no-hardcoded-user-text", asRuleModule(rule), {
{
// Without the option the brand word is reported: the exclusion is
// configuration, not a hardcoded constant inside the rule.
code: "<span>easy-png-tools</span>",
code: "<span>easy-image-tools</span>",
filename: "Component.svelte",
errors: [{ messageId: "hardcodedText" }],
},
@@ -156,8 +156,8 @@ describe("hasUserWords", () => {
});
it("accepts configured brand words", () => {
expect(hasUserWords("easy-png-tools", ["easy-png-tools"])).toBe(false);
expect(hasUserWords("easy-png-tools")).toBe(true);
expect(hasUserWords("easy-image-tools", ["easy-image-tools"])).toBe(false);
expect(hasUserWords("easy-image-tools")).toBe(true);
});
it("accepts formats and units next to real copy", () => {
+1 -7
View File
@@ -178,13 +178,7 @@ export default tseslint.config(
i18n: i18nPlugin,
},
rules: {
"i18n/no-hardcoded-user-text": [
"warn",
{
// The product name is a brand, not translatable text.
allowWords: ["easy-png-tools"],
},
],
"i18n/no-hardcoded-user-text": "warn",
},
},
{
+9 -11
View File
@@ -1,6 +1,4 @@
// Generates static/og/default.png: the default 1200x630 OG card.
// Run: pnpm --dir web gen:og. The card is rendered in a browser (text,
// icons); per-tool cards will reuse this harness (docs/plan-seo.md S1e).
import { mkdirSync } from "node:fs";
import { chromium } from "playwright";
@@ -13,26 +11,26 @@ function cardHtml() {
return `<!doctype html><html><body style="margin:0">
<div style="
width:${W}px;height:${H}px;box-sizing:border-box;
background:#0a120c;
background-image:linear-gradient(#12281a 1px, transparent 1px),linear-gradient(90deg,#12281a 1px, transparent 1px);
background:#272827;
background-image:linear-gradient(#373a37 1px, transparent 1px),linear-gradient(90deg,#373a37 1px, transparent 1px);
background-size:40px 40px;
display:flex;align-items:center;justify-content:space-between;
padding:80px;font-family:ui-monospace,'Cascadia Mono',Consolas,monospace;
border:3px solid #16a34a;
border:3px solid #009a5a;
">
<div>
<div style="
width:72px;height:72px;background:#86efac;color:#052e16;
display:flex;align-items:center;justify-content:center;
font-size:34px;font-weight:700;margin-bottom:32px;
">EP</div>
<div style="color:#86efac;font-size:56px;font-weight:700;letter-spacing:-1px;">easy-png-tools</div>
<div style="color:#a7c4b1;font-size:28px;margin-top:24px;">PNG utilities right in your browser</div>
<div style="color:#4d7c5f;font-size:22px;margin-top:16px;">Convert · Crop · Resize — locally, no uploads</div>
">EIT</div>
<div style="color:#c3eccd;font-size:56px;font-weight:700;letter-spacing:-1px;">easy-image-tools</div>
<div style="color:#92b39a;font-size:28px;margin-top:24px;">Image utilities right in your browser</div>
<div style="color:#009a5a;font-size:22px;margin-top:16px;">Convert · Crop · Resize — locally, no uploads</div>
</div>
<div style="
color:#86efac;width:300px;height:300px;border:3px solid #16a34a;
background:#0f1f14;display:flex;align-items:center;justify-content:center;
color:#86efac;width:300px;height:300px;border:3px solid #009a5a;
background:#3c3e3c;display:flex;align-items:center;justify-content:center;
"><div style="width:240px;height:240px;">${IMAGE_ICON}</div></div>
</div>
</body></html>`;
+2 -1
View File
@@ -1,4 +1,5 @@
<script lang="ts">
import { t } from "$lib/i18n/t";
import { SITE_URL } from "$lib/seo";
interface Props {
@@ -18,7 +19,7 @@
<meta name="description" content={description} />
<link rel="canonical" href={url} />
<meta property="og:type" content="website" />
<meta property="og:site_name" content="easy-png-tools" />
<meta property="og:site_name" content={t("brand")} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:url" content={url} />
+2 -1
View File
@@ -1,11 +1,12 @@
<script lang="ts">
import { version } from "../../../../package.json";
import { t } from "$lib/i18n/t";
const versionLabel = `v${version}`;
</script>
<footer class="preview-footer">
<span>easy-png-tools <b class="version">{versionLabel}</b></span>
<span>{t("brand")} <b class="version">{versionLabel}</b></span>
<span>© 2026</span>
</footer>
+3 -3
View File
@@ -18,8 +18,8 @@
<header class="topbar">
<a class="brand" href={resolve("/")}>
<span class="brand-mark">EP</span>
<span>easy-png-tools</span>
<span class="brand-mark">EIT</span>
<span>{t("brand")}</span>
{#if crumb}
<span class="crumb">{crumb}</span>
{/if}
@@ -28,7 +28,7 @@
<div class="top-actions">
<a
class="social"
href="https://github.com/Ku6epXBOCTuK/easy-png-tools"
href="https://github.com/Ku6epXBOCTuK/easy-image-tools"
target="_blank"
rel="noopener noreferrer"
aria-label={t("ui.github")}
@@ -7,7 +7,6 @@
<a href={resolve("/")}>{t("header.home")}</a>
<a href={resolve("/list-tools")}>{t("header.catalog")}</a>
<a href={resolve("/chains")}>{t("header.chains")}</a>
<a href={resolve("/kit")}>{t("header.uiKit")}</a>
</nav>
<style>
+2
View File
@@ -44,6 +44,8 @@ export type HeaderStrings = {
};
export type Dict = {
/** Product brand name; identical in every locale, kept here as the single source. */
brand: string;
header: HeaderStrings;
categories: Record<CategoryId | "all", string>;
home: Record<string, string>;
+4 -3
View File
@@ -1,6 +1,7 @@
import type { Dict } from "./dict";
export const en: Dict = {
brand: "easy-image-tools",
header: {
workspace: "Workspace",
catalog: "Catalog",
@@ -24,14 +25,14 @@ export const en: Dict = {
generate: "Generate",
},
home: {
defaultTitle: "easy-png-tools — PNG utilities right in your browser",
defaultTitle: "easy-image-tools — PNG utilities right in your browser",
heroTitle: "What do you want to do with the image?",
heroLead: "Find a tool — everything runs locally in your browser.",
restoreLast: "↩ Restore last: {title}",
changeTool: "← Change tool",
},
catalog: {
pageTitle: "All tools — easy-png-tools",
pageTitle: "All tools — easy-image-tools",
metaDescription:
"Full catalog of PNG utilities: convert, transparency, color, geometry, analysis and image generation.",
heading: "Tool catalog",
@@ -76,7 +77,7 @@ export const en: Dict = {
warnSizeLimitMissShort: "Over size limit",
},
savedChains: {
pageTitle: "Saved pipelines — easy-png-tools",
pageTitle: "Saved pipelines — easy-image-tools",
metaDescription:
"Your saved image pipelines: named tool chains stored locally in your browser.",
heading: "Saved pipelines",
+4 -3
View File
@@ -1,6 +1,7 @@
import type { Dict } from "./dict";
export const ru: Dict = {
brand: "easy-image-tools",
header: {
workspace: "Рабочая область",
catalog: "Каталог",
@@ -24,7 +25,7 @@ export const ru: Dict = {
generate: "Генерация",
},
home: {
defaultTitle: "easy-png-tools — PNG-утилиты прямо в браузере",
defaultTitle: "easy-image-tools — PNG-утилиты прямо в браузере",
heroTitle: "Что делаем с изображением?",
heroLead:
"Найдите инструмент — все операции выполняются локально в браузере.",
@@ -32,7 +33,7 @@ export const ru: Dict = {
changeTool: "← Сменить инструмент",
},
catalog: {
pageTitle: "Все инструменты — easy-png-tools",
pageTitle: "Все инструменты — easy-image-tools",
metaDescription:
"Полный каталог PNG-утилит: конвертация, прозрачность, цвет, геометрия, анализ и генерация изображений.",
heading: "Каталог инструментов",
@@ -78,7 +79,7 @@ export const ru: Dict = {
warnSizeLimitMissShort: "Больше лимита",
},
savedChains: {
pageTitle: "Сохранённые пайплайны — easy-png-tools",
pageTitle: "Сохранённые пайплайны — easy-image-tools",
metaDescription:
"Ваши сохранённые пайплайны изображений: именованные цепочки инструментов, хранятся локально в браузере.",
heading: "Сохранённые пайплайны",
+8 -4
View File
@@ -1,6 +1,10 @@
/**
* Public site URL for canonical/OG (absolute URLs including the GitHub Pages
* base path). After the domain purchase, change it here; `docs/plan-seo.md` section 6.
* Note: `$app/paths.base` does not work for this; it is relative.
* Public site URL for canonical/OG. From build-time `PUBLIC_SITE_ORIGIN` (set in
* CI), falling back to the production domain; `$app/paths.base` is relative and
* won't work here. `docs/plan-seo.md` section 6.
*/
export const SITE_URL = "https://ku6epxboctuk.github.io/easy-png-tools";
const rawOrigin = import.meta.env.PUBLIC_SITE_ORIGIN;
export const SITE_URL =
typeof rawOrigin === "string" && rawOrigin.trim() !== ""
? rawOrigin.trim().replace(/\/+$/, "")
: "https://easy-image-tools.com";
+1 -1
View File
@@ -35,7 +35,7 @@
</script>
<svelte:head>
<title>easy-png-tools / {chain?.name ?? t("header.pipeline")}</title>
<title>{t("brand")} / {chain?.name ?? t("header.pipeline")}</title>
<meta name="robots" content="noindex, nofollow" />
</svelte:head>
+2 -2
View File
@@ -18,14 +18,14 @@
{#if page}
<Seo
title={`easy-png-tools / ${pageTitle(page)}`}
title={`${t("brand")} / ${pageTitle(page)}`}
description={pageDescription(page)}
path={`/tools/${page.slug}`}
/>
{/if}
<svelte:head>
{#if !page}
<title>easy-png-tools / {t("toolPage.fallbackTitle")}</title>
<title>{t("brand")} / {t("toolPage.fallbackTitle")}</title>
{/if}
<meta name="robots" content="noindex, nofollow" />
</svelte:head>
+1
View File
@@ -0,0 +1 @@
easy-image-tools.com
+1 -1
View File
@@ -1,5 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<title>easy-png-tools</title>
<title>easy-image-tools</title>
<rect width="32" height="32" rx="7" fill="#2563eb"/>
<rect x="5" y="5" width="22" height="22" rx="4" fill="#ffffff"/>
<clipPath id="pic">

Before

Width:  |  Height:  |  Size: 920 B

After

Width:  |  Height:  |  Size: 922 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

+1 -1
View File
@@ -1,4 +1,4 @@
// Stylelint config: design-token enforcement for easy-png-tools.
// Stylelint config: design-token enforcement for easy-image-tools.
// FWHM: keeps the design system a single source of truth. Colors and sizes must
// come from prefixed tokens; direct color values are allowed only for the two
// brand tokens.