Following my previous introductory article on NextJS, we are going to use these elements to build a useful application. What we are going to build is a Momo Learn a language learning app.
Since this application uses quite a number of assets, I recommend that you start from this base branch.
In this starter project, we have a web application made up of 5 pages. You can see all the pages inside the (site) directory. As you can see, each page has its own dedicated directory and a page.js file inside of it. In that file, we have the contents of our page.
Furthermore, we have a layout.js file with some styles defined in it. What you should know is that this layout component is wrapped around all the pages in your site. If you want to test this, just add the below attribute onto the body tag in there:
Next, remove the style attribute and create a /components directory inside the /app one. Inside the /components directory create a /layout directory and inside of it create a /navigation one. Inside this one create a Navigation.jsx file. Inside that file paste the below:
"use client";importLinkfrom"next/link";import{ useState }from"react";exportconstNavigation=()=>{const[isMenuOpen, setIsMenuOpen]=useState(false);consttoggleMenu=()=>{setIsMenuOpen(!isMenuOpen);};const links =[{url:"/",caption:"Home",},{url:"/hiragana",caption:"Hiragana",},{url:"/katakana",caption:"Katakana",},{url:"/kanji",caption:"Kanji",},{url:"/readings",caption:"Readings"},];return(<nav className={`bg-white border-gray-200 dark:bg-gray-900`}><div className="flex items-center justify-between"><div className="flex items-center"><div className="mr-4 text-white"><a href="/" target="_blank"><img className="h-16 rounded-full" src="/logo.jpg" alt="Logo"/></a></div><button
className="text-white focus:outline-none lg:hidden" onClick={toggleMenu}><svg
className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">{isMenuOpen ?(<path
strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12"/>):(<path
strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16"/>)}</svg></button></div>{/* Mobile Menu */}<ul
className={`${ isMenuOpen
?"block lg:hidden text-white"// Show on mobile, hide on larger screens:"hidden"}`}>{links.map((item, index)=>(<li className="px-5 py-1" key={index}><Link href={item.url} target="_blank">{item.caption}</Link></li>))}{/* Add more navigation items as needed */}</ul>{/* Desktop Menu */}<ul className="hidden lg:flex lg:space-x-4 px-5 lg:items-center text-white">{links.map((item, index)=>(<li key={index}><Link href={item.url} target="_blank">{item.caption}</Link></li>))}{/* Add more navigation items as needed */}</ul></div></nav>);};
In the case of this navigation component, we use the useState hook which can only run on the client.
Finally, let's use the navigation component in our layout file, replace its contents as per below:
import"./globals.css";import{Inter}from"next/font/google";import{Navigation}from"./components/layout/navigation/Navigation";const inter =Inter({subsets:["latin"]});exportconst metadata ={title:"Momo",description:"Japanese Language Learning App",};exportdefaultfunctionRootLayout({ children }){return(<html lang="en"><body suppressHydrationWarning className={inter.className}><Navigation/></body></html>);}
Now, you can navigate through the pages using the new navigation component we just added. Next, let's create a footer component. In the /layout directory, create a /footer alongisde the /navigation directory. Inside the /footer directory create a Footer.jsx file and inside of it paste:
Next, import the Footer in the layout and use it. Finally our last 'layout' component namely a container. Create a /mainContainer directory and inside of it a MainContainer.jsx file in which paste the below:
exportconstMainContainer=({ children })=>{return(<div className="bg-indigo-500 min-h-screen text-white"><div className="container mx-auto">{children}</div></div>);};
Finally, replace the contents of the layout.js with this:
import"./globals.css";import{Inter}from"next/font/google";import{Navigation}from"./components/layout/navigation/Navigation";import{MainContainer}from"./components/layout/mainContainer/MainContainer";import{Footer}from"./components/layout/footer/Footer";const inter =Inter({subsets:["latin"]});exportconst metadata ={title:"Momo",description:"Japanese Language Learning App",};exportdefaultfunctionRootLayout({ children }){return(<html lang="en"><body suppressHydrationWarning className={inter.className}><Navigation/><MainContainer>{children}</MainContainer><Footer/></body></html>);}
Next, let's work on the homepage to bring some real life into our application. First let's create a /content folder inside the /components one and inside the /content directory, create a /showcase directory. Inside of it, create a Showcase.jsx file in which paste the below:
importImagefrom"next/image";importLinkfrom"next/link";exportconstShowcase=()=>{return(<><div className="flex flex-col md:flex-row mt-10"><div className="w-full md:w-1/2 p-4 flex items-center justify-center"><div className="p-4"><Image src="/girl_learns.avif" width={500} height={500} alt="Girl Learns Japanese"/></div></div><div className="flex flex-col md:flex-row mt-10 w-[80%] mx-auto md:w-[40%]"><div className="p-4 mt-5"><p className="text-xl py-5 md:py-0 lg:py-5">If you ever dreamed of speaking the Japanese language, you are in the right place!</p><p className="text-xl py-5 md:py-0">KawaiiLearn is your go-to app for learning
<Link className="p-5 hover:text-gray-800 underline" href="/hiragana">Hiragana,</Link><br /><Link className="p-5 hover:text-gray-800 underline" href="/katakana">Katakana</Link><br /> or
<Link className="p-5 hover:text-gray-800 underline" href="/kanji">Kanji</Link>as well as some reading.</p></div></div></div><div className="flex flex-col md:flex-row mt-10 w-[85%] mx-auto"><div className="w-full md:w-1/2 p-4 flex items-center justify-center">{/* card */}<div className="bg-white shadow-md border border-gray-700 rounded-lg max-w-sm dark:bg-gray-800"><a href="/hiragana" target="_blank"><Image src="/hiragana.png" width={500} height={500} alt="Hiragana Octopus"/></a><div className="p-5"><a href="/hiragana" target="_blank"><h5 className="text-white font-bold text-2xl tracking-tight mb-2">LearnHiragana</h5></a><p className="font-normal text-gray-700 mb-3 dark:text-gray-400">The most basic JapaneseScript that will allow you to read and
understand many things.</p><a
href="/hiragana" target="_blank" className="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 font-medium rounded-lg text-sm px-3 py-2 text-center inline-flex items-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">Go check Hiragana<svg
className="-mr-1 ml-2 h-4 w-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path
fillRule="evenodd" d="M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z" clipRule="evenodd"></path></svg></a></div></div></div><div className="w-full md:w-1/2 p-4 flex items-center justify-center">{/* card */}<div className="bg-white shadow-md border border-gray-200 rounded-lg max-w-sm dark:bg-gray-800 dark:border-gray-700"><a href="/katakana" target="_blank"><Image className="rounded-md" src="/kana.jpg" width={500} height={500} alt="Kana face"/></a><div className="p-5"><a href="/katakana" target="_blank"><h5 className="text-gray-900 font-bold text-2xl tracking-tight mb-2 dark:text-white">LearnKatakana</h5></a><p className="font-normal text-gray-700 mb-3 dark:text-gray-400">Next level,for even more words in your vocabulary is of course
Katakana.</p><a
href="/katakana" target="_blank" className="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-3 py-2 text-center inline-flex items-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">Go check Katakana<svg
className="-mr-1 ml-2 h-4 w-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path
fillRule="evenodd" d="M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z" clipRule="evenodd"></path></svg></a></div></div></div></div><div className="flex flex-col md:flex-row mt-10 w-[85%] mx-auto"><div className="w-full md:w-1/2 p-4 flex items-center justify-center">{/* card */}<div className="bg-white shadow-md border border-gray-200 rounded-lg max-w-sm dark:bg-gray-800 dark:border-gray-700"><a href="/kanji" target="_blank"><Image className="rounded-md" src="/kanji_tokyo.avif" width={500} height={500} alt="Kanji for Tokyo"/></a><div className="p-5"><a href="/kanji" target="_blank"><h5 className="text-gray-900 font-bold text-2xl tracking-tight mb-2 dark:text-white">LearnKanji</h5></a><p className="font-normal text-gray-700 mb-3 dark:text-gray-400">There are thousands of them and you need them fortrue mastery
of the language, but do not worry!It is easier than you think
to start learning them.</p><a
href="/kanji" target="_blank" className="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-3 py-2 text-center inline-flex items-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">Go check Kanji<svg
className="-mr-1 ml-2 h-4 w-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path
fillRule="evenodd" d="M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z" clipRule="evenodd"></path></svg></a></div></div></div><div className="w-full md:w-1/2 p-4 flex items-center justify-center">{/* card */}<div className="bg-white shadow-md border border-gray-200 rounded-lg max-w-sm dark:bg-gray-800 dark:border-gray-700"><a href="/readings" target="_blank"><img className="rounded-t-lg" src="girl_reading.jpg" alt=""/></a><div className="p-5"><a href="/readings" target="_blank"><h5 className="text-gray-900 font-bold text-2xl tracking-tight mb-2 dark:text-white">Readings</h5></a><p className="font-normal text-gray-700 mb-3 dark:text-gray-400">Once you've mastered some of the reading and writing basics, you
should definitely test out your knowledge with some of our
stories.</p><a
href="/readings" target="_blank" className="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-3 py-2 text-center inline-flex items-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">Go check stories
<svg
className="-mr-1 ml-2 h-4 w-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path
fillRule="evenodd" d="M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z" clipRule="evenodd"></path></svg></a></div></div></div></div></>);};
Next, replace the contents of the page.js file that is located at the root of the /app directory with this:
import{Showcase}from"./components/content/showcase/Showcase";exportdefaultfunctionHome(){return(<div className="pt-10"><h1 className="text-3xl font-bold text-center">こんにちは</h1><p className="text-3xl font-bold text-center">Welcome to MomoLearn</p><Showcase/></div>);}
Now our homepage looks good, let's move on to the other pages. Let's start with the 'Hiragana' page. In the /components/content directory create a Header.jsx file and inside of it paste the below:
This component will help us render the GIFs showing how to draw the characters in the scripts.
Next create a Diacritics.jsx component:
importLinkfrom"next/link";exportconstDiacritics=({ diacritics })=>{return(<div className="text-center"><p className="text-3xl m-5">Dakuten and Handakuten</p><p className="text-white leading-8 mx-auto px-5 py-2 w-full sm:w-6/12">Now that you know how to draw the characters, you should also know
something about the
<Link className="p-1 hover:text-gray-800" href="https://paulbaptist.com/introduction-to-japanese-writing-hiragana-group-11-dakuten-%E3%81%8C%E3%81%96%E3%81%A0%E3%81%B0-etc/" target="_blank">Dakuten(゛)</Link> and
<Link className="p-1 hover:text-gray-800" href="https://skdesu.com/en/dakuten/" target="_blank">Handakuten(゚)</Link>.</p><p className="text-white leading-8 mx-auto px-5 py-2 w-full sm:w-6/12">These dyacritics will change a bit some of the vowels we've just
learned:</p>{diacritics.map((d)=>{return d.dakuten?(<p className="leading-8 pb-5" key={d.dakuten}><span className="p-1 text-2xl">{d.kana}({d.translation})</span> used with the dakuten(゛) will become
<span className="p-1 text-2xl">{d.dakuten}({d.dakutenTranslation})</span>{d.variant?(<span className="block">*The character {d.kana} also has a variant namely{" "}{d.variant.value}</span>):("")}{d.handakuten?(<span className="leading-8 block"><span className="p-1 text-2xl">{d.kana}({d.translation})</span> used with the handakuten(゚) will become
<span className="p-1 text-2xl">{d.handakuten}({d.handakutenTranslation})</span></span>):("")}</p>):("");})}</div>);};
import{HiraganaDyagraphsInfo}from"./hiragana/HiraganaDyagraphsInfo";import{KatakanaDyagraphsInfo}from"./katakana/KatakanaDyagraphsInfo";exportconstDyagraphs=({ dyagraphs, hiragana =false, katakana =false,})=>{return(<div className="text-center p-5">{hiragana &&<HiraganaDyagraphsInfo/>}{katakana &&<KatakanaDyagraphsInfo/>}{dyagraphs.map((d)=>{return(<p
className="text-white leading-8 mx-auto px-5 py-2 w-full sm:w-6/12" key={d.dyagraph}><span className="p-1 text-2xl">{d.dyagraph}({d.translation})</span>{d.dakuten?(<span className="block"> used with the dakuten(゛) will become
<span className="p-1 text-2xl">{d.dakuten}({d.dakutenTranslation})</span></span>):("")}{d.handakuten?(<span className="block"> used with the handakuten(゚) will become
<span className="p-1 text-2xl">{d.handakuten}({d.handakutenTranslation})</span></span>):("")}</p>);})}</div>);};
Next let's add our PracticeSection.jsx component:
import{Char}from"../client/Char";import{CharType}from"../client/CharType";exportconstPracticeSection=({ words, alphabet, type })=>{return(<><div className="mt-10 text-center p-5"><h1 className="text-2xl m-5">Practice time!</h1><p>Practice makes perfect so for starters I will give you some words with the {type} characters.</p><div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-5 lg:grid-cols-5 xl:grid-cols-5 gap-4 center">{words.map((w)=>{return<Char w={w}/>;})}</div></div><div className="mt-10 text-center p-5"><h1 className="text-2xl m-5">Writing time!</h1><p>Let's see if you can recognize the characters correctly</p><div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-5 lg:grid-cols-5 xl:grid-cols-5 gap-4 center">{alphabet.map((w)=>{return<CharType w={w}/>;})}</div></div></>);};
This component will render a section that allows the users to practice remembering the characters. As you can see we are using two new components inside of it. These will be client side components. Inside the /components/content directory create a new one named /client. Inside of it create the Char.jsx component:
This component will let user type in readings for a character and provide feedback whether the reading provided is right or wrong.
Next create an ImageComponent.tsx:
importImagefrom"next/image";exportconstImageComponent=({ imageSrc, imageAlt, script })=>{return(<div><p className="text-white leading-8 mx-auto px-5 py-2 w-full sm:w-6/12">As a final practice material,I will also give you this cute little
table with{script} characters:</p><div className="mt-10 flex items-center justify-center p-5"><Image src={imageSrc} width={0} height={0} priority
sizes="100vw" style={{width:"600px",height:"auto"}} alt={imageAlt}/></div></div>);};
Next, inside the /components/content directory, create a /hiragana one and inside of it create the HiraganaDyagraphsInfo.jsx component:
importLinkfrom"next/link";exportconstHiraganaDyagraphsInfo=()=>{return(<><p className="text-3xl m-5">HiraganaDyagraphs</p><p className="text-white leading-8 mx-auto px-5 py-2 w-full sm:w-6/12">If you thought the fun part is over when it comes to this script, you
are wrong, my friend!In hiragana we also have these
<Link className="p-1 hover:text-gray-800 underline" href="https://www.wattpad.com/1027156152-language-book-japan-edition-hiragana-digraphs" target="_blank">Dyagraphs</Link> which are basically groups of the
<span className="text-2xl">や(Ya),ゆ(Yu),よ(Yo)</span> vowels plus a
consonant.Let's have a look at them:</p></>);};
Next, create the HiraganaInfo.jsx component:
importLinkfrom"next/link";exportconstHiraganaInfo=()=>{return(<p className="mt-6 leading-8"><Link className="p-1 hover:text-gray-800 underline" href="/hiragana">Hiragana</Link> is the basic Japanese alphabet.Contrary to the English alphabet however, each
character represents one syllable sound.Below, you will find a quick reference
for how to draw each of the symbols.</p>);};
Still inside the /components/content directory, create a /katakana directory. Inside create the KatakanaDyagraphsInfo.jsx file:
importLinkfrom"next/link";exportconstKatakanaDyagraphsInfo=()=>{return(<><p className="text-3xl m-5">KatakanaDyagraphs</p><p className="text-white leading-8 mx-auto px-5 py-2 w-full sm:w-6/12">Just like
<Link className="p-1 hover:text-gray-800 underline" href="/hiragana">Hiragana</Link>,<Link className="p-1 hover:text-gray-800 underline" href="/katakana">Katakana</Link> has its own
<Link className="p-1 hover:text-gray-800 underline" href="https://www.japanesepod101.com/lesson/how-to-write-in-japanese-hiragana-and-katakana-19-the-katakana-y-column-and-more-digraphs" target="_blank"> dyagraphs
</Link>.Let's have a look at them:</p></>);};
Next, create the KatakanaInfo.jsx:
importLinkfrom"next/link";exportconstKatakanaInfo=()=>{return(<p className="mt-6 leading-8"><Link className="p-1 hover:text-gray-800 underline" href="/katakana">Katakana</Link> is the exact equivalent of<Link className="p-1 hover:text-gray-800 underline" href="/hiragana">Hiragana</Link> when it comes to pronounciation.The main difference is how the characters
look and when they are used.They look completely different from<Link className="p-1 hover:text-gray-800 underline" href="/hiragana">Hiragana</Link> and are more angular.Only a few characters look similar(like か -hiragana
/ カ -katakana).They are used for foregin or loan words.</p>);};
Next, inside /components/client create also a /kanji directory. Inside of it create the KanjiInfo.jsx component:
importLinkfrom"next/link";exportconstKanjiInfo=()=>{return(<><div><p className="mt-6 leading-8"><Link className="p-1 hover:text-gray-800 underline" href="/kanji">Kanji</Link> is the mos widely used Japanese script.However it is not native to Japan, it was brought in and adapted fromChina.</p></div></>);};
Finally after all of this, fill in the contents of the page.js file inside the /(site)/hiragana directory:
Now that the hiragana page is done, let's move on to the katakana one. In the /(site)/katakana/page.js file paste the below:
import{StrokeOrder}from"../../components/content/StrokeOrder";import{Diacritics}from"../../components/content/Diacritics";import{Dyagraphs}from"../../components/content/Dyagraphs";import{PracticeSection}from"../../components/content/PracticeSection";import{HeaderComponent}from"../../components/content/Header";import{ImageComponent}from"../../components/content/ImageComponent";import{ diacritics, dyagraphs }from"../../(site)/katakana/data";import{ katakanaWords, katakanaAlphabet }from"../../(site)/katakana/data";exportconst metadata ={title:"Katakana",description:"Page to learn Katakana",};exportdefaultfunctionKatakana(){return(<><HeaderComponent script="Katakana" imgSrc="/assets/katakana/katakana_fu_bu.webp" imgAlt="Katakana fu bu" katakana
/><StrokeOrder script={katakanaAlphabet} indexes={[35,38,43]} scriptName="katakana"/><Diacritics diacritics={diacritics}/><Dyagraphs dyagraphs={dyagraphs} katakana /><PracticeSection words={katakanaWords} alphabet={katakanaAlphabet} type="katakana"/><ImageComponent script="katakana" imageAlt="katakana fu bu girl" imageSrc="/assets/katakana/katakana_characters.jpg"/></>);}
Since we reused the previous components this page was super easy to create. Let's move on to the kanji page. First in the /components/content/client/kanji directory add the KanjiExtra.jsx file:
importLinkfrom"next/link";importImagefrom"next/image";exportconstKanjiExtra=()=>{return(<div className="mt-10 text-center p-5 w-120"><p><Link className="p-1 hover:text-gray-800 underline" href="/kanji">Kanji characters
</Link> are not sylables(unlike
<Link className="p-1 hover:text-gray-800 underline" href="/hiragana">Hiragana</Link> or
<Link className="p-1 hover:text-gray-800 underline" href="/katakana">Katakana</Link>).The characters actually represent a concept or an idea.</p><p>I will give you another quick example forstarters:</p><Image src="/assets/kanji/japan_kanji.webp" width={300} height={300} alt="Japan kanji" className="mx-auto my-5"/><p>As you notice from the picture, the
<Link className="p-1 hover:text-gray-800 underline" href="/hiragana" target="_blank">Hiragana</Link> characters alongside the
<Link className="p-1 hover:text-gray-800 underline" href="/kanji" target="_blank">Kanji</Link> are called
<Link className="p-1 hover:text-gray-800 underline" href="/https://storylearning.com/learn/japanese/japanese-tips/what-is-furigana" target="_blank"> furigana
</Link> and their role is to help us understand the prononciation of the
<Link className="p-1 hover:text-gray-800 underline" href="/kanji" target="_blank">Kanji</Link>.</p><div className="w-[100%] mx-auto md:w-[80%]"><p>The word <span className="text-2xl">日本</span> can also be written as<span className="text-2xl"> にほん</span> or
<span className="text-2xl"> にっぽん</span>.</p><p className="text-center text-2xl my-5">Kanji pronounciation</p><p className="text-center"><Link className="p-1 hover:text-gray-800 underline" href="/kanji" target="_blank">Kanji</Link> characters have multiple pronounciations, which makes it tricky to learn
them, but getting started should not be that hard.I will give you a quick
example.</p><p className="text">The symbol:<span className="text-2xl">人</span> is the{" "}<Link className="p-1 hover:text-gray-800 underline" href="/kanji" target="_blank"> kanji
</Link>for person.It is normally pronounced
<span className="text-2xl">ひと</span>.Yet,if we combine it with another
<Link className="p-1 hover:text-gray-800 underline" href="/kanji" target="_blank"> kanji
</Link> such as<span className="text-2xl">日本人</span> we get the word{" "}<span className="text-2xl">にほんじん</span>(this being the word forJapanese person).</p><p className="text-center text-2xl my-5">Onyomi and Kunyomi</p><p className="text-center">These are the 2 main ways in which{" "}<Link className="p-1 hover:text-gray-800 underline" href="/kanji" target="_blank">Kanji</Link> are read.Onyomi is the original Chinese pronounciation of the character(and it is used in compond words),whileKunyomi is the Japanesereading(and used in stand alone words).</p><p className="text">Let's go back to the <span className="text-2xl">人</span>.TheKunyomi reading forthis character is <span className="text-2xl">ひと</span>while the Onyomi reading is <span className="text-2xl">ジン</span>.</p></div></div>);};
Next, in the same directory add the StrokeOrderKanji.jsx file:
Finally, in the /(site)/kanji/page.js file paste the below:
import{HeaderComponent}from"../../components/content/Header";import{KanjiExtra}from"../../components/content/kanji/KanjiExtra";import{StrokeOrderKanji}from"../../components/content/kanji/StrokeOrderKanji";importImagefrom"next/image";importLinkfrom"next/link";exportconst metadata ={title:"Kanji",description:"Page to learn Kanji",};exportdefaultfunctionKanji(){return(<><HeaderComponent script="Kanji" imgSrc="/assets/kanji/kanji_songoku.png" imgAlt="songoku kanji furigana" kanji
/><KanjiExtra/><StrokeOrderKanji/><div className="w-[100%] mx-auto md:w-[80%] text-center"><p>Now that you know how to get started with</p>{" "}<Link className="p-1 hover:text-gray-800 underline" href="/kanji">Kanji</Link>, you just need to practice a bit more and get used to them litle by little.</div><div className="mt-10 pb-10 flex items-center justify-center"><Image src="/assets/kanji/kanji_study.webp" width={500} height={500} priority
alt="girl learns kanji"/></div></>);}
Our application is almost ready, let's now just finish up by adding the readings page. First we will need one more client component created inside /components/content/client namely StorySentence.jsx:
This will be a component that will let the users toggle the romaji reading of the story sentences so they can practice reading better. Once you have the component, paste the below contents inside /(site)/readings/page.js:
importImagefrom"next/image";import{ readings }from"./data";import{StorySentence}from"../../components/client/StorySentence";importLinkfrom"next/link";exportconst metadata ={title:"Readings",description:"Page to learn Readings",};exportdefaultfunctionKatakana(){return(<><h1 className="text-center m-auto text-3xl py-5">The story ofMomotaro</h1><div className="flex flex-col md:flex-col pt-10 justify-center text-2xl w-[80%] md:w-[60%] mx-auto"><p className="m-5">If you want to practice a bit your knowledge, feel free to read the
story below:</p></div><div className="mt-10 pb-10 flex items-center justify-center"><Image src="/momotaro-densetsu.jpg" width={500} height={500} priority
alt="girl learns kanji"/></div>{readings.map((r)=>{return<StorySentence text={r}/>;})}<div className="flex flex-col md:flex-col pt-10 justify-center text-2xl w-[80%] md:w-[60%] mx-auto"><p className="m-5">Now,ifI did pique your interest, you can read the full story here:<Link className="p-5 hover:text-gray-800 underline" href="https://www.lingual-ninja.com/folktales/Momotaro#Momotaro%20Story" target="_blank">FullMomotaro story
</Link></p></div></>);}
With this, you have implemented your first application with NextJS and I really hope you've learned a thing or two about how to use the framework. Also, if you want to dig in some more, feel free to check this article. If you want to compare your code against mine, I have the repo here. Also you can see the app live here.