This is a solution to the Shortly URL shortening API Challenge challenge on Frontend Mentor. Frontend Mentor challenges help you improve your coding skills by building realistic projects.
In this challenge I continued practicing React and I also made myself comfortable with styled components.
Users should be able to:
- View the optimal layout for the site depending on their device's screen size
- Shorten any valid URL
See a list of their shortened links, even after refreshing the browser- Copy the shortened link to their clipboard in a single click
- Receive an error message when the
form
is submitted if:- The
input
field is empty
- The
- Solution URL: Frontend Mentor
- Live Site URL: Netlify
- Semantic HTML5 markup
- CSS custom properties
- Flexbox
- Mobile-first workflow
- React - JS library
- Styled Components - For styles
I enjoy styled components a lot, having the styling close to the functionality makes developing components a breeze, not to mention sass integration! The following block of code was how I initially layed out the 'logo' component in the navbar.
From this:
const Logo = () => {
const logo = {
fill: '#232127',
width: '6em',
height: '3em',
}
return (
<svg className={logo}>
<use href={sprite + '#logo'} />
</svg>
)
}
To this:
const StyledLogo = styled.svg`
fill: #232127;
width: 6em;
height: 3em;
`
const Logo = () => {
return (
<StyledLogo>
<use href={sprite + '#logo'} />
</StyledLogo>
)
}
No biggie, but it looks nicer.
- The :hover state on mobile' article I'm mentioning in the Useful resources comes down to this fix:
&:active {
background-color: hsl(257, 7%, 63%);
}
@media (hover: hover) and (pointer: fine) {
&:hover {
cursor: pointer;
background-color: hsl(180, 72%, 80%);
transition: background-color 300ms;
}
&:active {
background-color: hsl(257, 7%, 63%);
}
}
}
Using @media (hover: hover) and (pointer: fine)
to differentiate the touchscreen capable devices from ordinary computers. This prevents the button from being stuck with the hover effect when tapped and thus no confused user.
-
I learned how to use
async
functions and how to manage api calls. In case of a bad request, the error code will go through a switch statement and the message displayed under input text will comply with the API table of errors. -
One aspect I had to tackle with was how will the inserted link get passed into the api call. Some users including myself feel more natural hitting the Enter button after pasting a link. At first I though about having an event listener on the document and on every keyboard input, it will be checked if 'Enter' was pressed, if it was, then the input text will be attached to the api method. However, I don't like the idea of monitoring every keystroke so I modified the input container from a
<div>
to a<form>
. Now the button in the form would to the job but, when submitting a form the page reloads, so nowe.preventDefault()
is mandatory in the API call function. -
Ugly form buttons.
input[type='submit']
is unstylable so they have to be replaced with ordinary buttons.
- I also cleared the unrealistic errors, for example, error 3 regarding the rate limit will never be displayed because the user won't be able to send a second request until the button animation stops.
error | meaning |
---|---|
error_code:2 | Invalid URL submitted |
error_code:4 | IP-Address has been blocked because of violating our terms of service |
error_code:6 | Unknown error |
error_code:10 | Trying to shorten a disallowed Link. More information on disallowed links |
- The use of
navigator.clipboard.writeText(newLink)
throws an error when executed in development stage but works fine on the final build.
When importing through the svg sprite the illustration is rendered improperly, gradients are not visible and it seems like the layers are mixed up. I double checked the svg sprite because it was made in 'svg sprite generator', I looked for missing lines of code but it was right. I ended up importing the image individually through img
tag. I don't know the cause of this, I commented out the lines with use
so I can retry this anytime.
I didn't find a proper way to list all the links that were passed through. I did find some articles about functional components and got advice on slack but I still couldn't manage to get them to work. I believe I could've split the input section in smaller components and pass props in order to generate a component for each link, inside the section. After spending hours with this task I decided to find an alternative of showing the links and move on with the challenge, sitting too much on an issue would just not help as much as noting it down and doing some research afterwards.
Further, I want to continue using React on my following projects. I also want to adopt a11y practices and make every site more accesible.
Some of the stuff I wrote about seem trivial but writing them down while working helps me carry over to the next project all the stuff I learnt tackling the current one.
- solution to :hover on touchscreens - This article guided me on how to deal with the problematic hover states on mobile.
- Frontend Mentor - @popescudragos
- LinkedIn - @ospop