5 Questions a Beginner Developer Might Have About the French Writing Playground Version 2.0
Published: November 15, 2025 • 8 min read
I have a confession to make. Taking this application from Version 1 to Version 2 took me longer than I expected. This morning, I made the final changes, and the app is now fully developed to my liking, so yayyy! As part of documenting this building process in my SDR Era, I thought it'd be useful to create a sort of Q&A blog. Except this time, I am the person asking the questions from the perspective of what I believe a beginner developer would ask and then responding to the questions as well.
So here goes: 5 questions I think a beginner developer might have about Version 2.0 of the French Writing Playground application.
Question 1: You said the application uses Next.js. What is that?
Okay listen, Next.js might sound fancy, but if you are a beginner developer in the 21st century, you have probably heard of or worked with React, you know, the popular library for building interfaces? Think of Next.js as a complete framework that adds many features on top of React.
One of the most popular of these extra features is File-based routing. What this means is that instead of manually setting up routes, you just create files in folders and Next.js automatically creates pages. For example, creating src/app/about/page.tsx automatically creates a /about page. Because of this, you can't just import and use components as pages like you do in React.
If you've worked with React, Next.js will be a breeze to handle.
Question 2: You mentioned that the application uses the Glassmorphism design trend. How is that implemented in the code?
Okay, so if you've read some of the previous blog posts, you will probably know by now that Glassmorphism is my favorite design trend, and I only learned about it through my web development experience at Outlier, where I had to build and review multiple full-stack applications built in 3-6 hour time frames.
Anyways, when you use the French Writing Playground application, you will notice that it has a sort of frosted glass appearance with blur, transparency, and subtle borders. It is kind of like looking through a frosted bathroom window where you can see shapes and colors behind it, but they're blurred and soft. Glassmorphism recreates this effect digitally, making UI elements feel modern, elegant, and layered.
The Three Variants of Glassmorphism
There are 3 variants of Glassmorphism:
- glass: This is the standard frosted glass effect
- glass-strong: Similar to the above but more opaque and has a greater blur effect
- glass-subtle: This variant has a very light and subtle glassmorphism effect
These 3 variants above combine the following CSS properties that define how they look:
backdrop-filter: blur()- Blurs whatever is behind the elementbackground: rgba()- Semi-transparent white backgroundborder- Subtle light border to define edgesbox-shadow- Soft shadow for depth
You can think of the variants as CSS classes that you can apply to different elements within your application, and each of these variants have different definitions for the CSS properties listed above.
Making Text Readable on Glass
While I love Glassmorphism, I do acknowledge that text can sometimes be harder to read on a glass surface. This is why I had to use text-readable or heading-readable classes for text inside the glass elements. text-readable and heading-readable work because they have a text-shadow property defined which creates a dark shadow behind text to increase contrast, making white/light text readable on ANY background.
Question 3: How were you able to make the app have multiple different colors based on the different themes chosen?
Well, the simple answer to this question is variables! But let's break it down a bit more.
I have a specific file which contains all the emotions and their specific color palette, including primary, secondary, accent, text, etc. While the application uses Tailwind, I could not use static Tailwind classes to define colors as the theme colors change dynamically based on the user's selected emotion.
So when I need to set an element to use the primary color of the current theme, for instance, I use selectedTheme.color.primary.
How Theme Switching Works
To handle theme switching, the application uses Zustand (state management) to store the current emotion globally. So when a user changes their emotion on the app, a function is called to update the global state. Then all affected components will automatically re-render with the new theme colors and styles.
Question 4: How come the header and footer show up when viewing certain pages like the write and collage page, but then you only see a side navigation when you visit the dashboard, quiz or messaging area?
Easy! Remember above when I mentioned that Next.js uses file-based routing? Well, an extension of this file-based routing is something called Route groups.
What Are Route Groups?
Route groups are folders wrapped in parentheses () that you can use to organize your code without affecting the URL structure. They let you group related pages together and apply shared layouts, but the parentheses folder name doesn't appear in the URL.
So the /write, /collage, and /feedback pages, as well as some other pages, have the same route group. Then the messaging page and dashboard page have a different route group as well.
How Layouts Work
These route groups have a layout.tsx file that determines how they render on the front end by wrapping pages with shared UI elements. The layout.tsx file of the route group that contains the /write and /collage pages specifies that the header and footer must be visible when viewing these pages. However, the layout.tsx file of the route group for the messaging and quiz page specifies that the side dashboard must be visible when viewing these pages.
Question 5: I don't speak French so I tried testing your application with a random string of text and even English words, but it rejected the submission and never got evaluated. Are you using AI for that?
Good question! No, actually. You see, AI is great, but we software developers must not forget that there are deterministic and cost-effective approaches to handling certain types of validation. I do not want the French Writing Playground application to be abused, so I implemented several layers of validation before the text ever reaches the OpenAI API.
Layer 1: Pattern Detection
Catches gibberish by analyzing:
- Text entropy
- Detecting keyboard mashing patterns (qwerty, asdfgh)
- Excessive repetition
- Spam-like URLs
Layer 2: Language Validation
Ensures actual French writing by requiring:
- 30% recognizable French words
- French accents (é, è, à)
- Proper contractions (l', d')
Only after passing all these deterministic checks does the text get sent to OpenAI for CEFR evaluation. This approach saves me money (no wasted API calls on gibberish) and provides instant feedback to users who submit invalid text - no waiting for an AI response just to find out they typed nonsense!
Why This Matters
I'm a jobless recent graduate managing API costs carefully. These validation layers are essential for keeping the app sustainable while preventing abuse.
What's Next?
And that's all for today. I'll be releasing more blog posts responding to questions from the perspective of an intermediate as well as senior developer about the application, so stay tuned!
Try out the French Writing Playground V2.0 and see these features in action!
As always, thanks for reading!