? Что такое Web Share API?
В этом посте мы рассмотрим, как можно добавить кнопки общего доступа Svelte в ваше приложение на базе Svelte. Мы будем следовать подходу, основанному на использовании встроенных API браузера, а не на добавлении дополнительных пакетов или зависимостей. Мы будем работать в SvelteKit, хотя наши компоненты Svelte могут быть использованы в приложениях Slinkity или Astro Svelte.
Мы добавляем кнопки в блог-старт, которые позволяют посетителям сайта делиться записями блога со своими друзьями и подписчиками в WhatsApp, Telegram и Twitter, а также Facebook. Эта функциональность работает в любом браузере, опираясь только на JavaScript. Кроме того, мы используем относительно новый API Web Share. На мобильном телефоне посетителя появляется меню, позволяющее легко поделиться вашим сайтом в любом установленном приложении. Мы используем подход прогрессивного улучшения. Это означает, что на мобильных устройствах (и в Safari на настольных компьютерах) будет отображаться кнопка Web Share API, в то время как браузеры, которые еще не поддерживают ее, будут показывать вместо нее наши кнопки обмена.
? Что мы создаем
Я упоминал, что мы работаем в SvelteKit, используя стартер блога MDsveX. Если Astro — ваш любимый инструмент для создания сайтов Svelte, начните с Astro Svelte Markdown starter. Конечно, если у вас есть существующее приложение Svelte, вы можете создать ветку функций и добавить эту функциональность туда. В любом случае, для начала давайте клонируем репозиторий:
git clone https://github.com/rodneylab/sveltekit-blog-mdx.git sveltekit-share-buttons
cd sveltekit-share-buttons
pnpm install
cp .env.EXAMPLE .env
pnpm run dev
После этого мы начнем с добавления функциональности кнопки fallback share. Мы подробно рассмотрим добавление Twitter, а затем перейдем к добавлению других сетей. Если вы хотите добавить популярную сеть, которая не упоминается, оставьте комментарий ниже, и я посмотрю, что можно сделать. Кроме того, не стесняйтесь отправить запрос в репозиторий, если вы создадите поддержку известной сети, которая еще не реализована.
? Начальный компонент кнопки поделиться
Чтобы начать работу, давайте создадим папку src/lib/components/ShareButton
и добавим в нее файл index.svelte
. Этот файл в конечном итоге будет содержать логику прогрессивного улучшения Web Share, а также обратные действия. Прогрессивное улучшение выражает настроение, схожее с изящной деградацией. Идея заключается в том, что мы хотим поддержать новую функцию, которая в настоящее время не пользуется широкой поддержкой. У нас есть базовая линия, которая поддерживает все (или большинство) устройств, затем прогрессивное улучшение предлагает новую функцию, но только там, где пользовательское устройство ее поддерживает.
Чтобы начать работу, вставьте этот код в новый файл:
<script>
import Twitter from '$lib/components/ShareButtons/Twitter.svelte';
import website from '$lib/config/website';
const { siteUrl } = website;
export let slug;
export let title;
const url = `${siteUrl}/${slug}`;
</script>
<aside aria-label="Share buttons" class="container">
<div class="wrapper">
Share: <div class="buttons">
<Twitter {url} {title} />
</div>
</div>
</aside>
Вот некоторые дополнительные стили, которые вы можете вставить в конец файла:
<style lang="scss">
.container {
display: flex;
flex-direction: row;
margin-top: $spacing-12;
width: $max-width-full;
}
.wrapper {
display: flex;
flex-direction: row;
margin-left: auto;
font-weight: $font-weight-bold;
font-size: $font-size-2;
}
.buttons {
margin-left: $spacing-4;
}
button {
background: transparent;
border-style: none;
transition: all 0.2s ease-in-out;
}
@media (prefers-reduced-motion: reduce) {
button {
transition: all 2s ease-in-out;
}
}
button:focus,
button:hover {
transform: scale(1.1);
}
</style>
Это пока не сработает — нам нужно создать компонент кнопки поделиться Twitter. Тем не менее, давайте добавим компонент ShareButton
в наш шаблон записи блога сейчас:
<script>
import BannerImage from '$lib/components/BannerImage.svelte';
import SEO from '$lib/components/SEO/index.svelte';
import ShareButtons from '$lib/components/ShareButtons/index.svelte';
import readingTime from 'reading-time';
<BannerImage {imageData} />
<h1>{title}</h1>
<ShareButtons {slug} {title} />
После этого мы создадим компонент кнопки поделиться в Twitter. Другие компоненты работают аналогичным образом, но API Twitter поддерживает наибольшее количество настроек, поэтому он является хорошей отправной точкой.
? Компонент кнопки поделиться Твиттером
Эта кнопка будет частью резервного копирования; поэтому мы не будем показывать ее на устройствах, поддерживающих Web Share API. В настоящее время на MacOS Safari поддерживает API, поэтому протестируйте эту часть в Firefox и Chrome. Код Twitter, а также другие компоненты кнопки поделиться основаны на репозитории nygardk/react-share GitHub Клауса Нюгорда.
<script>
import TwitterIcon from '$lib/components/Icons/Twitter.svelte';
export let hashtags = []; // array of hashtags exclude '#' e.g. ['svelte', 'askRodney']
export let quote = undefined;
export let related = []; // array of Twitter users (including '@')
export let title; // text in Tweet
export let url;
export let via = ''; // include '@' e.g. '@askRodney'
const TWITTER_BLUE = '#00aced';
const baseUrl = 'https://twitter.com/share';
const parametersObject = {
url,
...(hashtags.length > 0 ? { hashtags: hashtags.join(',') } : {}),
quote,
text: title,
...(related.length > 0 ? { related: related.join(',') } : {}),
...(via.length > 0 ? { via: via.slice(1) } : {}),
};
const params = Object.entries(parametersObject)
.filter(([, value]) => value ?? false)
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)
.join('&');
const urlWithParameters = params === '' ? baseUrl : `${baseUrl}?${params}`;
function handleClick() {
const config = {
height: 550,
width: 400,
location: 'no',
toolbar: 'no',
status: 'no',
directories: 'no',
menubar: 'no',
scrollbars: 'yes',
resizable: 'no',
centerscreen: 'yes',
chrome: 'yes',
};
return window.open(
urlWithParameters,
'',
Object.keys(config)
.map((key) => `${key}=${config[key]}`)
.join(','),
);
}
</script>
<button on:click={handleClick}
><span class="screen-reader-text">Share on Twitter</span><TwitterIcon
colour={TWITTER_BLUE}
width={48}
/></button
>
<style lang="scss">
button {
background: transparent;
border-style: none;
transition: all 0.2s ease-in-out;
}
@media (prefers-reduced-motion: reduce) {
button {
transition: all 2s ease-in-out;
}
}
button:focus,
button:hover {
transform: scale(1.1);
}
@media screen and (max-width: $desktop-breakpoint) {
button {
padding-left: $spacing-2;
padding-right: $spacing-2;
}
}
</style>
В строке 2
мы импортируем иконку iconify Twitter, уже используемую в проекте. С помощью iconify довольно легко добавлять иконки из десятков библиотек. На самом деле эта заметка является продолжением предыдущей, в которой рассказывается, как получить доступ к более чем 100 000 SVG-иконок с помощью одного пакета. Поэтому вернитесь туда, когда захотите узнать, как добавить иконки в свой проект.
API Twitter имеет большинство преимуществ: вы можете включить хэштеги, цитаты и связанные с ними аккаунты, а также учетную запись Twitter. Я добавил несколько комментариев в код, чтобы объяснить, как их использовать. Здесь мы просто сосредоточимся на добавлении текста (title
prop) и URL.
Настройки Twitter
Строки 14
—21
(выше) формируют параметры запроса для URL, который мы должны отправить в Twitter, чтобы поделиться постом. Поскольку это URL, некоторые символы недопустимы, и мы должны их закодировать. В строке 25
мы используем encodeURIComponent
для URL-кодирования ключей и параметров.
Код handleClick
в строках 30
—51
вызывает новое окно на сайте Twitter, которое позволяет посетителю войти в систему (если он еще не вошел) и поделиться информацией. Размеры являются разумными значениями по умолчанию, которые работают на устройствах разного размера, поэтому вам, скорее всего, не придется их корректировать.
Другие компоненты будут аналогичными, хотя и с разными baseUrl
(см. строку 13
). Для улучшения доступности включите на все кнопки текст для чтения с экрана (как в строке 55
). Этот текст не будет виден, но программы чтения экрана будут сообщать о нем, помогая пользователям программ чтения экрана узнать, что делает кнопка.
? Другие сетевые кнопки
Сейчас мы бегло рассмотрим другие сети, фактически, мы укажем только на детали, которые отличаются. Затем в следующем разделе мы добавим их в основной компонент, а также подключим Web Share API.
<script>
import FacebookIcon from '$lib/components/Icons/Facebook.svelte';
export let hashtag = '';
export let quote = '';
export let url;
const FACEBOOK_BLUE = '#3b5998';
const baseUrl = 'https://www.facebook.com/sharer/sharer.php';
const parametersObject = {
u: url,
...(quote !== '' ? { quote } : {}),
...(hashtag !== '' ? { hashtag } : {}),
};
const params = Object.entries(parametersObject)
.filter(([, value]) => value ?? false)
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)
.join('&');
const urlWithParameters = params === '' ? baseUrl : `${baseUrl}?${params}`;
function handleClick() {
const config = {
height: 550,
width: 400,
location: 'no',
toolbar: 'no',
status: 'no',
directories: 'no',
menubar: 'no',
scrollbars: 'yes',
resizable: 'no',
centerscreen: 'yes',
chrome: 'yes',
};
return window.open(
urlWithParameters,
'',
Object.keys(config)
.map((key) => `${key}=${config[key]}`)
.join(','),
);
}
</script>
<button on:click={handleClick}
><span class="screen-reader-text">Share on Facebook</span><FacebookIcon
colour={FACEBOOK_BLUE}
width={48}
/></button
>
<style lang="scss">
button {
background: transparent;
border-style: none;
transition: all 0.2s ease-in-out;
}
@media (prefers-reduced-motion: reduce) {
button {
transition: all 2s ease-in-out;
}
}
button:focus,
button:hover {
transform: scale(1.1);
}
@media screen and (max-width: $desktop-breakpoint) {
button {
padding-left: $spacing-2;
padding-right: $spacing-2;
}
}
</style>
Telegram
<script>
import TelegramIcon from '$lib/components/Icons/Telegram.svelte';
export let url;
export let title;
const TELEGRAM_BLUE = '#49a9e9';
const baseUrl = 'https://telegram.me/share/url';
const parametersObject = {
url,
text: title,
};
const params = Object.entries(parametersObject)
.filter(([, value]) => value ?? false)
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)
.join('&');
const urlWithParameters = params === '' ? baseUrl : `${baseUrl}?${params}`;
function handleClick() {
const config = {
height: 550,
width: 400,
location: 'no',
toolbar: 'no',
status: 'no',
directories: 'no',
menubar: 'no',
scrollbars: 'yes',
resizable: 'no',
centerscreen: 'yes',
chrome: 'yes',
};
return window.open(
urlWithParameters,
'',
Object.keys(config)
.map((key) => `${key}=${config[key]}`)
.join(','),
);
}
</script>
<button on:click={handleClick}
><span class="screen-reader-text">Share on Telegram</span><TelegramIcon
colour={TELEGRAM_BLUE}
width={48}
/></button
>
<style lang="scss">
@import '../../styles/variables';
button {
background: transparent;
border-style: none;
transition: all 0.2s ease-in-out;
}
@media (prefers-reduced-motion: reduce) {
button {
transition: all 2s ease-in-out;
}
}
button:focus,
button:hover {
transform: scale(1.1);
}
@media screen and (max-width: $desktop-breakpoint) {
button {
padding-left: $spacing-2;
padding-right: $spacing-2;
}
}
</style>
<script>
import { browser } from '$app/env';
import WhatsappIcon from '$lib/components/Icons/Whatsapp.svelte';
import { isMobileOrTablet } from '$lib/utilities/device';
const WHATSAPP_GREEN = '#25D366';
export let url;
export let title;
const baseUrl =
browser && isMobileOrTablet()
? 'https://api.whatsapp.com/send'
: 'https://web.whatsapp.com/send';
const parametersObject = {
text: title ? title + ' ' + url : url,
};
const params = Object.entries(parametersObject)
.filter(([, value]) => value ?? false)
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)
.join('&');
const urlWithParameters = params === '' ? baseUrl : `${baseUrl}?${params}`;
function handleClick() {
const config = {
height: 550,
width: 400,
location: 'no',
toolbar: 'no',
status: 'no',
directories: 'no',
menubar: 'no',
scrollbars: 'yes',
resizable: 'no',
centerscreen: 'yes',
chrome: 'yes',
};
return window.open(
urlWithParameters,
'',
Object.keys(config)
.map((key) => `${key}=${config[key]}`)
.join(','),
);
}
</script>
<button on:click={handleClick}
><span class="screen-reader-text">Share on Whatsapp</span><WhatsappIcon
colour={WHATSAPP_GREEN}
width={48}
/></button
>
<style lang="scss">
button {
background: transparent;
border-style: none;
transition: all 0.2s ease-in-out;
}
@media (prefers-reduced-motion: reduce) {
button {
transition: all 2s ease-in-out;
}
}
button:focus,
button:hover {
transform: scale(1.1);
}
@media screen and (max-width: $desktop-breakpoint) {
button {
padding-left: $spacing-2;
padding-right: $spacing-2;
}
}
</style>
В стартере еще нет значка WhatsApp. Добавьте этот код или создайте свой собственный, используя предпочитаемый набор значков:
<script>
import Icon, { addCollection } from '@iconify/svelte/dist/OfflineIcon.svelte';
export let label = 'Whatsapp icon';
export let colour = 'inherit';
export let ariaHidden = false;
export let width = 48;
addCollection({
prefix: 'simple-icons',
icons: {
whatsapp: {
body: '<path fill="currentColor" d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967c-.273-.099-.471-.148-.67.15c-.197.297-.767.966-.94 1.164c-.173.199-.347.223-.644.075c-.297-.15-1.255-.463-2.39-1.475c-.883-.788-1.48-1.761-1.653-2.059c-.173-.297-.018-.458.13-.606c.134-.133.298-.347.446-.52c.149-.174.198-.298.298-.497c.099-.198.05-.371-.025-.52c-.075-.149-.669-1.612-.916-2.207c-.242-.579-.487-.5-.669-.51a12.8 12.8 0 0 0-.57-.01c-.198 0-.52.074-.792.372c-.272.297-1.04 1.016-1.04 2.479c0 1.462 1.065 2.875 1.213 3.074c.149.198 2.096 3.2 5.077 4.487c.709.306 1.262.489 1.694.625c.712.227 1.36.195 1.871.118c.571-.085 1.758-.719 2.006-1.413c.248-.694.248-1.289.173-1.413c-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 0 1-5.031-1.378l-.361-.214l-3.741.982l.998-3.648l-.235-.374a9.86 9.86 0 0 1-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884c2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 0 1 2.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0 0 12.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 0 0 5.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 0 0-3.48-8.413Z"/>',
},
},
width: 24,
height: 24,
});
// https://api.iconify.design/simple-icons.json?icons=whatsapp
</script>
<Icon icon="simple-icons:whatsapp" {ariaHidden} aria-label={label} color={colour} {width} />
Также для WhatsApp существуют разные URL API в зависимости от того, использует ли посетитель мобильное устройство или нет. Мы используем служебную функцию для проверки типа устройства пользователя. Создайте этот файл, если вы добавили в свое приложение приведенный выше код кнопки WhatsApp share:
/**
* Returns true if the device is thought to be a mobile or tablet
* @returns {boolean}
*/
export function isMobileOrTablet() {
return /(android|iphone|ipad|mobile)/i.test(navigator.userAgent);
}
? Собираем все вместе
Теперь мы возвращаемся к src/lib/components/ShareButtons/index.svelte
, чтобы связать новые кнопки. Не стесняйтесь опустить здесь все сети, которые не понадобятся в вашем приложении.
<script>
import Facebook from '$lib/components/ShareButtons/Facebook.svelte';
import Telegram from '$lib/components/ShareButtons/Telegram.svelte';
import Twitter from '$lib/components/ShareButtons/Twitter.svelte';
import Whatsapp from '$lib/components/ShareButtons/Whatsapp.svelte';
import website from '$lib/config/website';
const { siteUrl } = website;
export let slug;
export let title;
const url = `${siteUrl}/${slug}`;
</script>
<aside aria-label="Share buttons" class="container">
<div class="wrapper">
Share: <div class="buttons">
<Twitter {url} {title} /><Facebook {url} /><Whatsapp {url} {title} />
<Telegram {url} {title} />
</div>
</div>
</aside>
Думаю, будет понятно, что мы здесь делаем, но дайте мне знать, если я забыл что-то объяснить!
? Web Share API
Последний недостающий элемент — это кнопка Web Share. Мы добавим булевую переменную webShareAPISupported
с реактивным объявлением. Это требует доступа к объекту браузера navigator
, поэтому не будет работать, когда код выполняется на стороне сервера. SvelteKit предоставляет переменную browser
, определенную в $app/env
, которую мы используем здесь. Если вы работаете в Astro, проверьте наличие ssr
с помощью этого фрагмента:
// ASTRO ONLY - IGNORE FOR SVELTEKIT
const ssr = import.meta.env.SSR;
Помните, что когда browser
в коде SvelteKit будет true
, ssr
будет false (и наоборот).
В любом случае, давайте обновим файл:
<script>
import { browser } from '$app/env';
import ShareIcon from '$lib/components/Icons/Share.svelte';
import Facebook from '$lib/components/ShareButtons/Facebook.svelte';
import Telegram from '$lib/components/ShareButtons/Telegram.svelte';
import Twitter from '$lib/components/ShareButtons/Twitter.svelte';
import Whatsapp from '$lib/components/ShareButtons/Whatsapp.svelte';
import website from '$lib/config/website';
const { siteTitle, siteUrl } = website;
export let slug;
export let title;
$: webShareAPISupported = browser && typeof navigator.share !== 'undefined';
$: handleWebShare;
const handleWebShare = async () => {
try {
navigator.share({
title,
text: `Shared from ${siteTitle}`,
url,
});
} catch (error) {
webShareAPISupported = false;
}
};
const url = `${siteUrl}/${slug}`;
</script>
<aside class="container">
<div class="wrapper">
Share: <div class="buttons">
{#if webShareAPISupported}
<button on:click={handleWebShare}
><span class="screen-reader-text">Share</span><ShareIcon width={48} /></button
>
{:else}
<Twitter {url} {title} /><Facebook {url} /><Whatsapp {url} {title} />
<Telegram {url} {title} />{/if}
</div>
</div>
</aside>
В строке 17
мы объявляем функцию handleWebShare
реактивной, используя синтаксис доллара. Это позволит интерфейсу обновляться, если в строке 26
функция установит webShareAPISuported
в false
.
Что мы имеем?
В строках 35
—41
у нас есть защита, поэтому если webShareAPISupported
будет false
, пользователь увидит кнопки share, которые мы определили ранее. С другой стороны, если значение true
, пользователь увидит кнопку share, которую мы добавим через некоторое время.
Когда пользователь нажимает или касается кнопки поделиться, вызывается функция handleWebShare
. Это асинхронный процесс, поэтому лучше всего включать блоки try
/catch
. Если по какой-то причине обмен не удастся, это не проблема! Помните, что у нас есть запасной вариант, поэтому просто покажите кнопки share для сетей, которые мы добавили изначально. Строки 20
—24
содержат основной код Web Share.
Совместное использование через API
API Web Share позволяет пользователям обмениваться ссылками, текстом и файлами. Здесь мы сосредоточимся на обмене текстом и ссылками. Чтобы поделиться файлом, просто добавьте дополнительное поле files
в объект share. Мы обмениваемся ссылкой и связанным с ней текстом. Вы можете поделиться одним из них самостоятельно и отказаться от другого (некоторые браузеры пока не поддерживают текст). Вы видите, что API довольно прост, и больше ничего не нужно объяснять… браузеры делают всю тяжелую работу! Последнее, о чем стоит упомянуть, это проверка поддержки в строке 15
. Для проверки последней версии поддержки браузерами смотрите документацию MDN Web Share API.
Иконка Share
Прежде чем приступить к тестированию, нам нужно вставить в проект недостающий значок общего доступа (не стесняйтесь заменить его, используя вашу коллекцию):
<script>
import Icon, { addCollection } from '@iconify/svelte/dist/OfflineIcon.svelte';
export let label = 'Share icon';
export let colour = 'inherit';
export let ariaHidden = false;
export let width = 24;
addCollection({
prefix: 'simple-line-icons',
icons: {
share: {
body: '<path fill="currentColor" d="M864 704c-52.688 0-99.295 25.585-128.431 64.88l-421.36-214.72c3.664-13.455 5.792-27.535 5.792-42.16c0-18.303-3.216-35.807-8.88-52.175l423.76-205.616C763.97 294.016 810.897 320 864.001 320c88.367 0 160-71.649 160-160c0-88.368-71.633-160-160-160S704 71.633 704 160c0 12.431 1.567 24.464 4.24 36.08L278.4 404.657c-29.281-32.273-71.393-52.656-118.4-52.656C71.631 352 0 423.633 0 512c0 88.351 71.631 160 160 160c50.895 0 96.127-23.824 125.423-60.865l423.104 215.632C705.664 838.736 704 851.152 704 864c0 88.368 71.632 160 160 160s160-71.632 160-160s-71.632-160-160-160zm.002-639.999c53.008 0 96 42.992 96 96s-42.992 96-96 96s-96-42.992-96-96s42.992-96 96-96zm-704 544c-53.024 0-96-42.992-96-96s42.976-96 96-96c53.008 0 96 42.992 96 96s-42.992 96-96 96zm704 352c-53.008 0-96-42.992-96-96s42.992-96 96-96s96 42.992 96 96s-42.992 96-96 96z"/>',
},
},
width: 1024,
height: 1024,
});
// https://api.iconify.design/simple-line-icons.json?icons=share
</script>
<Icon icon="simple-line-icons:share" {ariaHidden} aria-label={label} color={colour} {width} />
? Svelte Share Buttons: Тест
Теперь вы должны увидеть кнопки поделиться, если откроете любую из записей блога в браузере. Для тестирования на настольном компьютере на момент написания статьи API WebShare не поддерживался в Firefox и Chrome, поэтому они подходят для тестирования кнопок возврата. Safari на настольном компьютере поддерживает WebShare API, поэтому он отлично подходит для тестирования этой кнопки. Также попробуйте развернуть ваше приложение в среде staging, чтобы протестировать несколько мобильных браузеров.
?? Svelte Share Buttons: Подведение итогов
В этом посте мы рассмотрели:
- как добавить кнопки обмена в приложение Svelte с помощью прогрессивного улучшения,
- использование Web Share API для публикации из приложения Svelte,
- добавление запасных иконок share с помощью iconify.
Я очень надеюсь, что в этой статье вы найдете хотя бы одну вещь, которую сможете использовать в своей работе или побочном проекте. Также дайте мне знать, если вы считаете, что необходимо более подробное объяснение конфигурации.
Этот пост появился в результате просьбы в комментарии к другому посту, поэтому оставьте комментарий ниже, если вы хотите увидеть видео или пост о чем-то еще.
Вы можете посмотреть полный код SvelteKit для этого проекта в репозитории Rodney Lab Git Hub. Если у вас возникнут какие-либо проблемы, вы можете оставить комментарий ниже, а также связаться с нами в чате Element. Также пишите в Twitter @mention, если у вас есть предложения по улучшению или вопросы.
?? Обратная связь
Если вы нашли это видео полезным, смотрите ссылки ниже для дальнейшего связанного контента на этом сайте. Я надеюсь, что вы узнали что-то новое из этого видео. Дайте мне знать, есть ли способы улучшить его. Я надеюсь, что вы будете использовать код или стартер в своих собственных проектах. Не забудьте поделиться своей работой в Twitter, упомянув меня, чтобы я мог увидеть, что у вас получилось. И наконец, не забудьте сообщить мне о своих идеях относительно других коротких видео, которые вы хотели бы увидеть. О том, как связаться со мной, читайте ниже. Если вы нашли этот пост полезным, даже если вы можете позволить себе лишь небольшой вклад, пожалуйста, поддержите меня через Buy me a Coffee.
Наконец, не стесняйтесь поделиться этим постом в своих социальных сетях для всех ваших подписчиков, которые найдут его полезным. Помимо того, что вы можете оставить комментарий ниже, вы можете связаться со мной через @askRodney в Twitter, а также askRodney в Telegram. Также смотрите другие способы связаться с Rodney Lab. Я регулярно пишу о SvelteKit, а также о поисковой оптимизации и других темах. Также подпишитесь на рассылку новостей, чтобы быть в курсе наших последних проектов.