Photo by Erik Mclean on Unsplash
Day 26: Filling the Gap
Me filling in the logs I left blank due to time constraints.
Table of contents
TLDR;
In this blog post, I want to share my experience participating in the 100DaysOfCode challenge while coding my school website. I'll talk about the challenges I faced, the progress I made, and the lessons I learned along the way. Whether you're a beginner or an experienced coder, I hope this post will inspire you to take on your coding challenges and make progress toward your goals.
Intro
I joined the #100DaysOfCode Challenge last Feb 23. I set my goal to have a personal portfolio by the end of the challenge. I was doing good for 2 days straight. But then my school website needed to be redone, so I volunteered to have it done as my part of the challenge. This way I have something fruitful right off the bat during the challenge other than my portfolio.
And hey, I still need something to fill up my showcase section. Win-win ๐ฅ! The deadline was March 16 eve. We intended to launch to the public on St. Patrick's Day, March 17. So, a website with all the bells & whistles, within 20 days. And I had to design a UI, decide on the tech stack, code it, deploy it, accumulate content. Yes, I was a Fullstack developer for the 1st time in my life for a real-world application. And I was the only developer ๐ญ.
Yes, this is the same school website I talked about a while back, management decided to hand over the development to an external company but it didn't work out quite so well, so here we are, starting from scratch ๐
Through this challenge, I faced many challenges and obstacles, including balancing my coding sessions with my other responsibilities, staying motivated and focused and figuring out how to overcome technical issues and bugs in the codebase. However, by sticking to the challenge and committing to coding every day, I was able to make significant progress on my school website project and improve my coding skills along the way.
Prelude
1) What the project demands
Our school website requires the following:-
A landing page
Showcase for the structure (logical)
Showcase the features (infrastructures)
A news portal
A blogging archive/space for the school's events and such
The real problem is how the website is structured so that a visitor can navigate the site intuitively without any hustle. So the site map became like...
I found this structure more suitable and can lead visitors to get where they want immediately based on their interest in the school itself.
2) The Tech Stack
I originally wanted to go with
Sveltekit (SSG) + Tailwind + Shared Hosting
Note: Shred Hosting is the final deployment option as the hosting is provided by the OBA & not in my control. So the entire decision was wrapped around the fact, of whether the end product can be run by a shared hosting provider. So, SSG
was the answer.
Still, there are dynamic parts, so I intended to have pseudo-Island architecture. i.e. the site is Static by default and client-side JavaScript is sprinkled here and there for dynamic content. Speaking of which are:-
authentication/authorization,
searching,
comments for blogs,
merch store (vague idea),
push notifications,
caching locally using
Service Workers
.
My first struggle is my choice. Though SvelteKit's SSG is a thing, but I couldn't figure out how it works. My dev build was alright, but when I deployed stuff i was getting 404s for some blogs.
Another problem was, how it finds which pages to render ahead of time. Link crawlers only rendered blogs of which links were found, not the others that will be visible via search etc.
So I had to change my strategies. I need a meta-framework that gets all the available paths to render ahead and then bundle it. Yes, you guessed it, I switched back to NextJs 13. So the stack is now
NextJs + Tailwind + Shared Hosting
Another thing that you might have noticed is, I am pointing 3 different but totally non-vital Tailwind on the stack, leaving out vital such as renderers, bundlers, dbs and such.
The focus and the client
That's because none of that really matters for the end product. My Client doesn't need to care how fast we are handling events, how efficiently we are touching and manipulating the DOM, or how Svelte is 13ms faster than react-labs is...
My Client only cares about the visuals. So my focal points be...
the functionality: NextJs
the visual: TailwindCSS
the presence: Shared Hosting
So, enough planning, let's get our hands dirty
System Design Phase
I already tweeted some of the screenshots of UI. Here are some for reference
1) Home
2) The Navigation
3) Blogs list view
mobile view...
4) Blogs detail view
5) Miscellaneous site
For more, please visit the end result โ
System Development
I wanted to point out a few new things I learned here.
1) SSG
I already told you the site is SSG mostly, for now, it IS. First I went with my all-time favorite, SvelteKit. SSG with SvelteKit is done by adding
// change the svelte.config.js
import adapter from '@sveltejs/adapter-static';
export default {
kit: {
adapter: adapter({
// default options are shown. On some platforms
// these options are set automatically โ see below
pages: 'build',
assets: 'build',
fallback: null,
precompress: false,
strict: true
})
}
};
// this goes to the +layout.svelte
export const prerender = true;
This was working fine, but at that time my problem was rendering all the pages. The svelte adapter essentially crawls the site for links and renders them. What if the links were to be loaded later, like a search?
One way was to get the slugs to blogs in list view and then the crawler takes care.
SvelteKit was hard for me
This is where I was confused, actually, I still am. The data were loaded from the page.ts file, but the load
function was also executing on the client side erroring in deployment because the CMS is not running in the client's 2368 port!
So I moved the load
function to page.server.js. ๐คฆโโ๏ธ. You can't have *.server.js file if the adapter is adapter-static. I gave up. I moved to NextJs. because the deadline is coming ahead.
Dumb is Intelligent
NextJs handles the SSG differently, unlike SvelteKit's crawler, NextJs relies on developer input at bundling time. This may feel like an overhead, but for me, it provided a manual and granular way to handle the SSG process.
NextJs way of SSG
Let's say we have a blog, the list view component be
export default function BlogList(props) {
const pages = props.pages;
return (
<section>
{pages.forEach((page) => (
<Link href={page.slug}>
<p>{page.title}</p>
</Link>
))}
</section>
);
}
Then we can get the needed data from getStaticProps
...
export async function getStaticProps() {
const res = await fetch('127.0.0.1:2368/ghost/api/content/page');
const pages = await res.json();
return {props: {pages}}
}
Now the blog details view component...
export default function BlogDetail(props) {
const page = props.pages[0];
return <main>
<h1>{page.title}</h1>
<p>
{page.plaintext}
</p>
</main>
}
The props are from...
export async function getStaticProps({ slug }) {
const res = await fetch('127.0.0.1:2368/ghost/api/content/page/slug/hey-there-its-me-birnadin-erick')
const page = await res.json();
return { props: { page } }
}
Then this is where NextJs stands out in my case, the getStaticPaths
function let you fine control.
export async function getStaticPaths() {
const res = await fetch('127.0.0.1:2368/ghost/api/content/page')
const pages = await res.json();
pages.map(page => { { params: { slug: page.slug } } })
return pages;
}
Now I can filter the slugs I needed based on any condition and sort them however I want. Sky is the limit.
This is how I planned the scheduling feature.
2) Blog authoring
The authors of the blog are not technical persons. My school vice-rector writes these articles (shout out to the man himself ๐ฅ) and by any means, he is interested in learning markdown or HTML. So WYSIWYG editor is needed. Where to? I love hashnode's Neptune. Unfortunately, it is a closed source as far as I know. So the closest prettier We could get is Ghost's.
Sudden brake
Yes, shamelessly I split this log into 2, maybe 3 I don't know, there are lots to cover. And it's 2319h here in Sri Lanka as I am writing. I am tired and need to sleep. So, see you in part 2.
Part 2 will address:
How I integrated Ghost's editor into our website
Deployment strategies
Plans for dynamic contents
How I like 0Auth for less headache
Plain PHP API for comments
Hope this makes sense, till we meet again, it's me the BE signing off ๐.