Svelte предоставляет лаконичный синтаксис для работы с реактивными данными и жизненным циклом. Интеграция timeago.js в Svelte минимальна по коду.
<!-- TimeAgo.svelte -->
<script>
import { format } from 'timeago.js';
export let date;
export let locale = 'ru';
</script>
<time datetime={date}>{format(date, locale)}</time>
<!-- LiveTimeAgo.svelte -->
<script>
import { onMount, onDestroy } from 'svelte';
import { format } from 'timeago.js';
export let date;
export let locale = 'ru';
let label = '';
let timer;
onMount(() => {
label = format(date, locale);
timer = setInterval(() => {
label = format(date, locale);
}, 60000);
});
onDestroy(() => {
clearInterval(timer);
});
</script>
<time {datetime}>
{label}
</time>
<script>
import { onMount, onDestroy } from 'svelte';
import { render, cancel } from 'timeago.js';
export let date;
export let locale = 'ru';
let el;
onMount(() => render(el, locale));
onDestroy(() => cancel(el));
</script>
<time bind:this={el} datetime={date} />
<script>
import { onMount, onDestroy, afterUpdate } from 'svelte';
import { render, cancel } from 'timeago.js';
export let date;
export let locale = 'ru';
let el;
let mounted = false;
onMount(() => {
mounted = true;
render(el, locale);
});
afterUpdate(() => {
if (!mounted || !el) return;
cancel(el);
render(el, locale);
});
onDestroy(() => cancel(el));
</script>
<time bind:this={el} datetime={date} />
<script>
import { onMount, onDestroy } from 'svelte';
import { format } from 'timeago.js';
export let date;
export let locale = 'ru';
let label = '';
let timer;
$: {
label = format(date, locale);
}
onMount(() => {
timer = setInterval(() => {
label = format(date, locale);
}, 60000);
});
onDestroy(() => clearInterval(timer));
</script>
<time datetime={date}>{label}</time>
Реактивное выражение $: пересчитывает label
при изменении date или locale.
// stores/locale.js
import { writable } from 'svelte/store';
export const locale = writable('ru');
<script>
import { format } from 'timeago.js';
import { locale } from '../stores/locale';
export let date;
$: label = format(date, $locale);
</script>
<time datetime={date}>{label}</time>
// actions/timeago.js
import { render, cancel } from 'timeago.js';
export function timeago(node, { locale = 'ru' } = {}) {
render(node, locale);
return {
update({ locale: newLocale }) {
cancel(node);
render(node, newLocale);
},
destroy() {
cancel(node);
},
};
}
Использование в шаблоне:
<script>
import { timeago } from '../actions/timeago';
</script>
<time use:timeago={{ locale: 'ru' }} datetime="2025-05-26T10:00:00Z" />
<script>
import { onMount, onDestroy } from 'svelte';
import { render, cancel } from 'timeago.js';
export let posts = [];
let container;
onMount(() => {
const nodes = container.querySelectorAll('time[datetime]');
render(nodes, 'ru');
});
onDestroy(() => cancel());
</script>
<ul bind:this={container}>
{#each posts as post (post.id)}
<li>
<h3>{post.title}</h3>
<time datetime={post.createdAt} />
</li>
{/each}
</ul>
// src/app.js
import App from './App.svelte';
import { register } from 'timeago.js';
import ru from 'timeago.js/esm/lang/ru';
register('ru', ru);
const app = new App({ target: document.getElementById('app') });
export default app;