Το πρόβλημα, ένα WordPress που έφτασε στα όριά του
Υπάρχει ένα σημείο όπου το WordPress σταματάει να βοηθάει και αρχίζει να εμποδίζει. Το Base Training το είχε περάσει από καιρό.
- 20+ ενεργά plugins: πολυγλωσσικό, caching, SEO —Yoast και Rank Math μαζί, το ένα να ακυρώνει το άλλο— φόρμες, μέλη, διαχείριση μαθημάτων, πληρωμές, marketing, analytics. Το καθένα με τους δικούς του πίνακες στη βάση και τη δική του ουρά.
- Ενημερώσεις που τσακώνονταν μεταξύ τους. Κάθε ενημέρωση του πυρήνα έσπαγε ένα ή δύο plugins, και κάθε διόρθωση σε plugin έσπαγε δύο άλλα.
- Φόρτωση 5 με 8 δευτερόλεπτα σε κινητό, με τα Core Web Vitals στο «poor» σε ολόκληρο το site.
- Πολυγλωσσικό χάος. Άρθρα σε πέντε γλώσσες, με χαμένες μεταφράσεις και canonical URLs που έδειχναν σε λάθος έκδοση.
- 3.000+ άρθρα που έκαναν πάνω από δώδεκα δευτερόλεπτα να εμφανιστούν σε μια απλή αναζήτηση στο sitemap.
- Downtime κάθε μήνα, από σύγκρουση plugins ή υπερφόρτωση της βάσης. Για κοινό που μπαίνει από όλες τις ζώνες ώρας, αυτό δεν είναι ενόχληση, είναι απώλεια.
- Κόστος φιλοξενίας εκτοξευμένο, από τις συνεχείς αναβαθμίσεις server μόνο και μόνο για να αντέχει τα plugins.
Η λύση, Symbols CMS πάνω στο Astro στο Cloudflare edge
Χτίσαμε custom πλατφόρμα με Astro για τη static-first αρχιτεκτονική, Symbols CMS ως επίπεδο επεξεργασίας, και Cloudflare Pages, Workers και D1 για το edge και το user state. Κάθε plugin αντικαταστάθηκε από κώδικα που κάνει μόνο αυτό που χρειάζεται και τίποτα παραπάνω.
Δεν είναι μεταφορά ένα προς ένα. Είναι ξεκαθάρισμα:
Το Astro παράγει στατικό HTML σε build time για τα 3.000+ άρθρα και τα 40+ προγράμματα, δημοσιευμένα σε 300+ κόμβους του Cloudflare. Μηδέν JavaScript by default, με islands μόνο για τα διαδραστικά κομμάτια — σύνδεση, πίνακας προόδου, ταμείο. Το bundle έπεσε από περίπου 2 MB σε λιγότερα από 60 KB.
Η μετάβαση, η πραγματική πρόκληση
Το δύσκολο δεν ήταν το νέο site. Ήταν να μη χαθεί τίποτα από τα παλιά:
- 3.000+ άρθρα σε πέντε γλώσσες, το καθένα με μεταδεδομένα, εικόνες, κατηγορίες, ετικέτες και εσωτερικούς συνδέσμους.
- 40+ ενεργά προγράμματα με εγγεγραμμένους χρήστες σε εξέλιξη. Κανείς δεν επιτρεπόταν να χάσει την πρόοδό του.
- Παλιά URLs με backlinks από fitness blogs και δημοσιεύσεις, δέκα ετών.
- Εγγραφές και πληρωμές σε εξέλιξη που δεν μπορούσαν να σταματήσουν ούτε για μία ώρα.
Η μεταφορά δεν έγινε με το χέρι — με τρεις χιλιάδες άρθρα δεν γίνεται. Έγινε με script που επικυρώνει το ίδιο του το αποτέλεσμα:
// scripts/migrate.ts — μεταφορά με έλεγχο, όχι με εμπιστοσύνη
const LOCALES = ['en', 'el', 'de', 'es', 'it'] as const;
for (const post of await fetchAllWpPosts()) {
const md = toMarkdown(post);
// Ένα άρθρο δεν περνάει αν του λείπει οτιδήποτε κρίσιμο για SEO.
assert(md.frontmatter.title, `${post.slug}: λείπει title`);
assert(md.frontmatter.description, `${post.slug}: λείπει description`);
assert(md.frontmatter.canonical, `${post.slug}: λείπει canonical`);
// Κάθε εικόνα πρέπει να κατέβηκε, αλλιώς θα βγει σπασμένη στο live.
for (const img of md.images) {
assert(await exists(img.localPath), `${post.slug}: χάθηκε ${img.src}`);
assert(img.alt?.trim(), `${post.slug}: εικόνα χωρίς alt`);
}
// Κάθε μετάφραση δείχνει στις αδελφές της, αλλιώς σπάει το hreflang.
const siblings = LOCALES.filter((l) => l !== md.lang);
for (const l of siblings) {
assert(md.translations[l], `${post.slug}: λείπει η έκδοση ${l}`);
}
await write(md);
}
Κάθε assert που σκάει είναι ένα άρθρο που δεν βγήκε στο live σπασμένο. Στο WordPress τα ίδια προβλήματα υπήρχαν ήδη — απλώς κανείς δεν τα μετρούσε.
Πέντε γλώσσες, σωστά
Το πολυγλωσσικό SEO είναι από τα πιο εύκολα πράγματα να τα κάνεις λάθος. Το παλιό setup τα είχε όλα τα κλασικά: διπλά canonical, χαμένα hreflang, ανάκατο sitemap. Η νέα δομή είναι ρητή και παράγεται μόνη της:
Οι διαδρομές δεν γράφτηκαν πέντε φορές. Ο κατάλογος των γλωσσών είναι μία γραμμή, και όλα τα υπόλοιπα —διαδρομές, hreflang, sitemaps— παράγονται από εκεί:
---
// src/pages/[lang]/[...slug].astro
const LOCALES = { en: 'programs', el: 'programmata', de: 'programme',
es: 'programas', it: 'programmi' } as const;
export async function getStaticPaths() {
const posts = await getCollection('posts');
return Object.keys(LOCALES).flatMap((lang) =>
posts.filter((p) => p.data.lang === lang)
.map((p) => ({ params: { lang, slug: p.data.slug }, props: { p } })),
);
}
const { p } = Astro.props;
const url = (l: string) => new URL(`/${l}/${p.data.translations[l]}/`, Astro.site);
---
<link rel="canonical" href={url(p.data.lang)} />
{Object.keys(LOCALES).map((l) => (
<link rel="alternate" hreflang={l} href={url(l)} />
))}
<link rel="alternate" hreflang="x-default" href={url('en')} />
Μια έκτη γλώσσα είναι μία γραμμή στο LOCALES. Στο WPML ήταν έργο.
Λιγότερα plugins σημαίνει και λιγότερα cookies
Ένα από τα plugins που έφυγαν δεν αντικαταστάθηκε από τίποτα: το cookie consent. Με τη μετάβαση σε cookieless analytics το site δεν αποθηκεύει πλέον cookies παρακολούθησης, οπότε δεν χρειάζεται banner συγκατάθεσης. Ο επισκέπτης δεν βλέπει πια παράθυρο να του κόβει την οθόνη στα πρώτα δύο δευτερόλεπτα, και η ομάδα δεν διαχειρίζεται πολιτικές συγκατάθεσης σε πέντε γλώσσες.
Είναι το είδος του κέρδους που δεν φαίνεται σε κανένα Lighthouse report, αλλά το νιώθει κάθε επισκέπτης.
Απόδοση, από «poor» σε 90+
Το 95% του site είναι προ-παραγόμενο σε build time· δυναμικά μένουν μόνο το user state και το ταμείο. Οι στατικές σελίδες σερβίρονται από τον κοντινότερο κόμβο, οπουδήποτε στον κόσμο. Τα islands φορτώνουν JavaScript μόνο όταν εμφανιστούν στην οθόνη. Οι εικόνες περνούν από το native pipeline σε WebP και AVIF με τέσσερα μεγέθη και ορισμένες διαστάσεις, οπότε το CLS μένει στο μηδέν. Το κρίσιμο CSS είναι inline, και το Cloudflare δίνει HTTP/3 με Brotli χωρίς ρύθμιση.
Lighthouse mobile από 50-60 στο 90+. Core Web Vitals όλα στο πράσινο.
Σχεδιασμένο για να μετατρέπει
Η ταχύτητα φέρνει τον επισκέπτη· δεν τον μετατρέπει. Οι σελίδες των προγραμμάτων έχουν σταθερό κουμπί «Ξεκίνα τώρα» πάντα ορατό, φόρμες με έλεγχο την ώρα που γράφεις και μηδενική τριβή, σταδιακή αποκάλυψη με τη σύνοψη πάνω και τις λεπτομέρειες πιο κάτω, μαρτυρίες δίπλα στα σημεία απόφασης αντί για μια ξεχωριστή σελίδα που δεν διαβάζει κανείς, και σύλληψη πρόθεσης εξόδου για όσους έφευγαν χωρίς να αφήσουν στοιχεία.
Τα νούμερα
Μέσα στους πρώτους μήνες, χωρίς νέο διαφημιστικό budget: +50% οργανική κίνηση, +38% leads, μηδέν downtime από την πρώτη μέρα, και δραστική μείωση του κόστους φιλοξενίας — η τιμολόγηση του Cloudflare είναι κλάσμα ενός dedicated WordPress server.
Και ένα νούμερο που δεν μπαίνει σε πίνακα: η συντήρηση πήγε από κάθε εβδομάδα σε μερικές φορές τον χρόνο.
Πότε το WordPress δεν είναι πια η απάντηση
Το WordPress ήταν εξαιρετικό εργαλείο για δεκαπέντε χρόνια, και για πολλά site εξακολουθεί να είναι σωστή επιλογή. Παύει να είναι όταν το έργο έχει σοβαρή κίνηση που δεν αντέχει να χαθεί, λειτουργεί σε πολλές γλώσσες, κουβαλάει πραγματική επιχειρησιακή λογική —μέλη, μαθήματα, συνδρομές— και όταν κανείς στην ομάδα δεν θέλει να ξυπνάει τη νύχτα επειδή έσπασε ένα plugin.
Το Base Training είχε και τα τέσσερα.
Δείτε την υπηρεσία μας κατασκευή ιστοσελίδων σε Astro Framework ή ζητήστε προσφορά για replatforming, να δούμε μαζί τι ακριβώς κερδίζετε.