Итак, есть бутстрап проектотличный продукт и мало клиентов, пришло время SEO. В общем, бутстреп или фриланс-проект улучшает многие навыки и учит больше концентрироваться на бизнесе (деньгах) и на том, что маркетологи не бездельники и у них тоже тяжелая работа!
Теперь будет несколько довольно простых вещей, которые я узнал и сделал за последние несколько дней (недель), и вы можете написать несколько умных советов в комментариях — я в вас верю!
Содержание
И так первый пункт, домен:
Говорят, что .com немного лучше, но в целом не важно какой, если он не новый, то репутация домена и ссылок еще лучше! Одним из факторов покупки нерентабельных, но перспективных проектов (в том числе доменов) является то, насколько легко их развивать, если знать, что делать.
У нас есть aso.dev — схватили как по волшебству за 98 долларов
Потом создаем сайт — нам нужно SEO, поэтому нужен рендеринг на сервере — все разговоры о том, что Google умеет парсить js — чушь собачья, потому что иногда это возможно, но ему это совсем не нравится, поэтому в этом нет необходимости. Можно взять какой-нибудь тяжелый SSR для React или Angular, но мы выбрали супер крутой, быстрый и простой. astro.buildкстати, у них достаточно простых и сложных вещей моделино в конце концов после экспериментов мы их взяли https://starlight.astro.build/ слегка переделав первую страницу (туда необходимо скопировать исходный код компонента Hero.astro) и заменить Head.astro.

Я в восторге, мы даже сайт нашего плеера переписываем мяу.приложение так как для него отлично работает динамический рендеринг на основе ответа API, и они попросили друга Джуна переписать его с нуля за небольшие деньги — для него это практика и реальный проект, а у нас есть более быстрый и простой сайт, использующий те же технологии, что и основной проект, поскольку Angular 14 уже не огонь, даже с универсальным рендерингом (ох как давно) — пример с astro(WIP)
Все прошло довольно хорошо, прежде чем воспроизводить изображения https://tinypng.com/ (вручную или через API и скрипт GPT), но теперь только с использованием стандартных инструментов astro.build.

Консоль поиска Google
Далее идет основа — вам нужно добавить Google Search Console, там вы сможете видеть свою индексацию, ошибки и получать достижения, а также публиковать их в Твиттер

https://search.google.com/search-console

На самом деле существует множество инструментов, сейчас я использую два бесплатных.
Арефс


Мне он очень понравился тем, что держит 10 000 запросов к сайту и анализирует все ваши страницы на наличие ошибок (все закрыть не получится, но мы сократим это до минимума).
Именно этот инструмент принес мне больше всего модификаций.
Улучшения и ошибки
Исправлена длина титульной страницы и страницы описания.
Для заголовка нужно 50-60 символов, для описания 110-160, в структуру метаинформации страниц (файлы .md) я их добавил как
seo:
seo_title: "All-in-One ASO Solution for iOS Developers, marketing"
seo_description: "ASO.dev is ultimate tool for App Store Optimization (ASO) with App Store Connect integration.Manage,optimize,grow your apps effortlessly with powerful features"
А потом я попросил gpt написать bash-скрипт для проверки этих файлов, с 30-й попытки это удалось сделать (все равно быстрее, чем я бы сделал в bash)
#!/bin/bash
divider="-----------------------------------"
# Function to check the length of seo_title and seo_description
check_seo_params() {
local file=$1
local in_seo_block=false
local seo_title=""
local seo_description=""
while IFS= read -r line
do
# Look for the start of the seo block
if [[ "$line" =~ ^seo: ]]; then
in_seo_block=true
fi
# If inside the seo block, search for seo_title and seo_description
if [[ "$in_seo_block" = true ]]; then
# Search for seo_title
if [[ "$line" =~ seo_title:[[:space:]]*\"(.*)\" ]]; then
seo_title="${BASH_REMATCH[1]}"
fi
# Search for seo_description
if [[ "$line" =~ seo_description:[[:space:]]*\"(.*)\" ]]; then
seo_description="${BASH_REMATCH[1]}"
fi
fi
# If the seo block ends (new block or end of file), stop reading
if [[ "$in_seo_block" = true && "$line" =~ ^[^[:space:]] && ! "$line" =~ ^seo ]]; then
in_seo_block=false
fi
done 60): '${seo_title}'"
have_errors=true
fi
# Check if seo_description is present and valid
if [[ -z "$seo_description" ]]; then
if [[ $have_errors = false ]]; then
echo $divider
echo $file
fi
echo "seo_description: Empty or not found"
have_errors=true
elif [[ ${#seo_description} -lt 110 || ${#seo_description} -gt 160 ]]; then
if [[ $have_errors = false ]]; then
echo $divider
echo $file
fi
echo "seo_description: Length ${#seo_description} (110 160): '${seo_description}'"
have_errors=true
fi
# Print divider only if there are no errors
# if [[ $have_errors = false ]]; then
# echo $divider
# fi
}
echo $divider
# Recursive search for all .md and .mdx files in the src/content/docs directory
find src/content/docs -type f \( -name "*.md" -o -name "*.mdx" \) | while read file; do
# Check if the file contains a seo block before proceeding
if grep -q "seo:" "$file"; then
check_seo_params "$file"
fi
done
echo $divider
Запускаем скрипт, переходим к файлу, копируем текст в GPT и запрашиваем оптимальный заголовок и описание, примерно так:
Write seo_title and seo_description, send the result in English, use best practices and length requirements for seo.
Result in the format:
```yaml
seo_title: ""
seo_description: ""
```
seo_title 50-60 symbols, seo_description 100-160 symbols
text is ...
Затем мы обновляем все страницы – это очень просто, я понимаю, но это лучше, чем ничего с теми же данными.
Любимый значок
Мы его немного сломали — неприятно сгенерировали файлы и метатеги через https://realfavicongenerator.net/ потом я проверил там работу.
Тег OG
Я немного побаловался оптимизацией, но перед этим создал og-теги — это мета-теги, которые позволяют вашей ссылке в социальных сетях или чатах отображать изображение, описание и обычно давать больше информации, чем просто ссылка. Их много, но мы должны хотя бы и: название, и: описание, и: изображение кстати, у него должен быть абсолютный путь, а все изображения (должны были) мы отдаем через кролик.нет но я кое-что понял и они всегда даются напрямую. Наш DNS находится на Cloudflare, и мы находимся в Хетцнер Облако используя Докер и владелец ранчо.
приложение/ld+json
Мы добавили application/ld+json — не уверен, что это так или иначе сработает, но выглядит круто — структурированная разметка данных
{
tag: "script",
attrs: {
type: "application/ld+json",
},
content: JSON.stringify({
"@context": "
"@type": "WebSite",
url: canonical?.href,
headline: ogTitle,
description: page_description_seo,
image: [imageUrl?.href],
mainEntity: {
"@type": "Article",
headline: page_description_seo,
url: canonical?.href,
dateModified: data?.lastUpdated,
image: [imageUrl?.href],
author: {
"@type": "Organization",
name: "ASO.dev",
url: "
},
publisher: {
"@type": "Organization",
name: "ASO.dev",
logo: {
"@type": "ImageObject",
url: fileWithBase(config.favicon.href),
},
},
},
}),
},
404
Мы создали кастомную страницу 404, по умолчанию все идет на индексную страницу и это считается ошибкой — не знаю, насколько серьезно это влияет, но помогает найти некорректные ссылки.
Конфигурация в Мете:
// 404
if (canonical?.pathname === "/404") {
headDefaults.push({
tag: "meta",
attrs: {
name: "robots",
content: "noindex",
},
});
}
Параметр в конфигурации nginx
location / {
proxy_redirect off;
absolute_redirect off;
proxy_set_header Host $http_host;
try_files $uri $uri/ =404;
# try_files $uri $uri/ /index.html;
add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0";
add_header Pragma "no-cache";
add_header Expires "Thu, 01 Jan 1970 00:00:00 GMT";
}
# 404 page
error_page 404 /404.html;
location = /404.html {
root /app;
internal;
}
перенаправляет
В итоге у нас получилось много 301 редиректов, поскольку мы решили, чтобы все ссылки заканчивались на /, чтобы https://aso.dev/aso/ И https://aso.dev/aso не получая дубликатов, в результате долгой проверки всех ссылок и отчетов — мы победили их все и нашли в коде с десяток старых ссылок. Мы поддерживаем перенаправления для старых ссылок в формате конфигурации nginx.
# rewrite ^(/ru|/en)?/app-info/app-info/?$ $1/aso/app-info/ permanent;
Более того, Copilot помогает вам их хорошо писать.
hreflang
Добавлен x-default для hreflang — не знал, что это нужно.
// Link to language alternates.
if (canonical && config.isMultilingual) {
for (const locale in config.locales) {
const localeOpts = config.locales[locale];
if (!localeOpts) continue;
const langPostfix = localeOpts.lang === "en" ? "" : localeOpts.lang;
headDefaults.push({
tag: "link",
attrs: {
rel: "alternate",
hreflang: localeOpts.lang,
href: localizedUrl(canonical, langPostfix).href,
},
});
}
headDefaults.push({
tag: "link",
attrs: {
rel: "alternate",
hreflang: "x-default",
href: localizedUrl(canonical, '').href,
},
});
}
семраш
https://www.semrush.com/projects/

Я пользуюсь им дольше, так что перейти на бесплатный план как-то проще, но лимит в 100 чеков и их цены не особо воодушевляют.
Обратная ссылка
Это простая и сложная вещь… Вам нужны ссылки на ваш сайт с других сайтов. Причём, если ссылка идёт со спам-сайта — это плохо (точно не +), а если с «Нью-Йорк Таймс», то одна ссылка даёт больше бонусов, чем сотни с сайта Васи Пупкина. Сейчас мы наращиваем ссылочную массу, размещая наш сайт на куче сайтов стартапов и независимых проектов, нашли файл Excel с сотней ссылок и постепенно его наполняем…
На охота за продуктами полезно для получения сильных ссылок — подписаться когда мы уедем, мы уже несколько раз откладывали это, но скоро уедем…
Ну и статьи тоже стараемся писать (полезные, не для галочки)
Возможно я что-то забыл, что-то неправильно написал — напишите в комментариях!