SEO от начинающего для незнающих

 Публичный пост
24 октября 2024  1696

Итак есть один бустрап проект, отличный продукт и мало клиентов, мое время дошло до SEO. Вообще бустрап или инди проект качает очень многие навыки и учит делать больше фокуса на бизнесе(деньгах) и что маркетологи не бездельники и у них тоже сложная работа!

Сейчас будут довольно базовые штуки, которые я узнал и сделал за последние пару дней(недель), а вы в комментариях можете написать умных советов - я верю в вас!

И так пункт первый, домен:

Говорят что .com немного лучше, но в целом пофиг какой, если не новый - то даже лучше -репутация домена и ссылки! Один из факторов покупки не прибыльных но имеющих потенциал проектов (доменов в том числе) в легкости их раскачки, если знаешь что делать.

У нас aso.dev - оторвали магически за 98 баксов

Дальше делаем сайт - нам нужна SEO, так что нужен серверный рендеринг - все разговоры, что гугл умеет парсить js - фигня, так как иногда может, но вообще не любит, поэтому не надо. Можно взять какой-то тяжеловесный SSR для react или Angular, но мы выбрали супер классный, быстрый и простой astro.build, у них кстати хватает простых и сложных шаблонов, но в итоге после экспериментов мы взяли их https://starlight.astro.build/ немного переделав первую страницу (там надо скопировать к себе исходник компонента Hero.astro) и override Head.astro.

Я от него в восторге, мы уже даже переписываем сайт нашего плеера meows.app так как динамический рендеринг на базе ответа от API у него работает супер, а переписать с нуля попросили знакомого джуна за небольшие деньги - ему практика и реальный проект, а у нас более быстрый и простой сайт на тех же технологиях что и основной проект, так как Angular 14 уже не огонь, даже с Universal рендеринг (ох, как давно это было) - пример с astro(WIP)

Довольно неплохо вышло, раньше картинки мы жали через https://tinypng.com/ (вручную или через API и скрипт от GPT), но сейчас просто стандартными средствами astro.build

Google search console

Дальше база - надо зайти и добавить Google Search Console, там можно увидеть свою индексацию, ошибки и получать ачивки, а их публиковать в твиттер

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

Инструментов на самом деле очень много, я пока пользуюсь двумя бесплатными

Ahrefs

User login - Ahrefs

Мне он очень понравился тем что там есть 10к запросов к сайту и анализ всех ваших страниц по ошибкам (закрыть все не получится, но сокращаем до минимума).

Именно этот инструмент дал мне наибольшее количество правок.

Улучшения и ошибки

Исправление длины title и description страницы

Для title необходимо 50-60 символов, для description 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 < "$file"

  local have_errors=false

  # Check if seo_title is present and valid
  if [[ -z "$seo_title" ]]; then
    echo $divider
    echo $file
    echo "seo_title: Empty or not found"
    have_errors=true
  elif [[ ${#seo_title} -lt 50 || ${#seo_title} -gt 60 ]]; then
    echo $divider
    echo $file
    echo "seo_title: Length ${#seo_title} (50 <> 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 и просим оптимальный title и description, примерно таким промтом:

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 ...

Дальше обновляем все страницы - это супер базово, я понимаю, но лучше чем ничего с одинаковыми данными.

Favicon

Мы его немного сломали - неприятно, нагенерировал файлов и мета тэгов через https://realfavicongenerator.net/ и там же потом проверил работу.

OG теги

Я немного пошел в оптимизацию, но до этого я сделал og теги - это такие мета-теги, которые позволяют вашей ссылке в социальных сетях или чатах показывать картинку, описание и вообще давать больше информации чем просто ссылка. Их довольно много, но нужно как минимум og:title, og:description, og:image , он кстати должен быть с абсолютным путем, а все картинки мы отдаем(должны были) через bunny.net но я что-то намудрил и они пока отдаются напрямую. Картинки к посту я сложил туда - чтобы было удобнее постить статью на разных платформах(посмотрим сколько это. будет денег), на vas3k кстати все хорошо из локального черновика перенеслось, а на хабре я плюнул(чуть позже переборю себя - ссылки нужны, о них ниже).
DNS у нас на Cloudflare, а хостимся мы в hetzner с помощью docker и rancher

application/ld+json

Добавили application/ld+json - не уверен что оно как-то сработает, но вроде прикольно - structured data markup

 {
        tag: "script",
        attrs: {
            type: "application/ld+json",
        },
        content: JSON.stringify({
            "@context": "https://schema.org",
            "@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: "https://aso.dev",
                },
                publisher: {
                    "@type": "Organization",
                    name: "ASO.dev",
                    logo: {
                        "@type": "ImageObject",
                        url: fileWithBase(config.favicon.href),
                    },
                },
            },
        }),
    },

404

Создали кастомную страницу 404, по умолчанию все идет в index page и это считается ошибкой - не знаю насколько это серьезно влияет, но она помогает найти неправильные ссылки.

Настройка в мете:

// 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;
        }

redirects

У нас оказалось очень много 301 редиректов, так как мы выбрали чтобы все ссылки были в конце с / , чтобы на https://aso.dev/aso/ и https://aso.dev/aso не получать дублирования, в результате долгой проверки всех ссылок и отчетов - мы их все победили и нашли десяток старых ссылок в коде. Редиректы для старых ссылок мы поддерживаем в nginx конфиге форматом

  # https://aso.dev/app-info/app-info/ https://aso.dev/aso/app-info/
  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,
        },
    });
}

semrush

https://www.semrush.com/projects/

Я с ним более давно, так он как-то проще конвертит в бесплатный тариф, но лимит в 100 проверок и их цены не особо радуют.

Это простая и сложная вещь... Вам нужны ссылки на ваш сайт с других сайтов. Причем если ссылка будет со спам сайта - это плохо (точно не +), а если с NYT - то одна ссылка дает больше бонусов, чем сотни с сайта Васи Пупкина. Мы пока наращиваем ссылочную массу тем что размещаем наш сайт на куче площадок про стартапы и инди-проекты, нашли Excel файл где сотни ссылок и постепенно его заполняем...

На producthunt для получения сильных ссылок полезно - подпишитесь на наш выход, мы его несколько раз уже переносили, но скоро выйдем...

Ну а еще стараемся писать статьи (полезные, а не для галочки)

Возможно я что-то забыл, что-то написал неправильно - напишите в комментарии!

Связанные посты
24 комментария 👇

О! Сеошечка пошла, а у меня в черновиках уже давно лежит пост-кумовство на обмен ссылками.

Суть простая: вы ставите ссылку на мой сайт где-то у себя в блоге, я ставлю ссылку на ваш.

Расчехлять пост?

  Развернуть 1 комментарий
🕵️ Юзер скрыл свои комментарии от публичного просмотра...
🕵️ Юзер скрыл свои комментарии от публичного просмотра...
Gleb A. Lantsman Преподаю IELTS, делаю онлайн-курсы 28 октября 2024

спасибо за прекрасную статью!

  Развернуть 1 комментарий

Спасибо за статью!

Я как человечек, который только вкатывается со своим проектом в инди / соло пренерство безмерно благодарен.

Я так понимаю этот чек-лист - это первые шаги в SEO? А можно ссылками, что нужно дальше? Я пока только работают над лендингом для продукта, но хотелось бы понимать заранее, на что нужно обратить внимание. И если не так разжевано по шагам, как тут, то можно ссылками в advanced штуки.

  Развернуть 1 комментарий

@hvms6k, я как выучу и пойму что дальше - постараюсь новый пост сделать, на данный момент все мои знания тут :D

  Развернуть 1 комментарий
🕵️ Юзер скрыл свои комментарии от публичного просмотра...

Спасибо за базу, особенно за tinypng - у меня крепко пригорало что я не могу нормально пожать картинки чтобы они не превращались в мыло. И за Google search console спасибо!

  Развернуть 1 комментарий

Когда базовые гигиенические вещи сделаешь интересно какую видишь seo стратегию?

Это один из каналов привлечения, и по нему можно пробовать считать CAC. От этого могут быть приняты какие-то решения, строить ли PDN, сколько вкладывать в блог и вообще контент маркетинг, какая афилейтная программа (это связанные вещи), кто конкуренты и нужны ли тебе всякие около-серые схемы, как одно время были pdf, или коменты в ютубе пока гугл их не прикрыл.

Ну а там гляди дойдет и до поведенческих факторов (время на сайте, и прочее)

По поводу агентств - вот лайфхак. Большинство предлагают бесплатный seo аудит как замануху, чтоб получить лида. Можешь с несколькими пройти и послушать о чем речь пойдет. Почти уверен будет полезно на этом этапе.

  Развернуть 1 комментарий

А какая целевая аудитория?

Я имею в виду, по странам в том числе.

Например, Россия запрещает поисковикам отображать сайты размещённые на определённых хостингах, скажем DreamHost.

Так что если вы ищете клиентов в России, SEO может совершенно Не сработать, в зависимости от того какой у вас web host, и какая в данный момент политика партии.

Просто для примера - всё это варьируется по локациям.

  Развернуть 1 комментарий

@Alex_Gift, для нас цель №1 - это США, ну и Европа. Вот думаем еще сайт на испанский перевести (чтобы в Латан пойти)

  Развернуть 1 комментарий
Игорь Кравченко flutter developer and founder автор 29 октября 2024
  Развернуть 1 комментарий

😎

Автор поста открыл его для большого интернета, но комментирование и движухи доступны только участникам Клуба

Что вообще здесь происходит?


Войти  или  Вступить в Клуб