You can put two or more projects into the same repository without opting in to a "monorepo" where every project goes into the same repository by default.
If you have multiple products that need to be released in tandem putting them in the same repository allows you to release all of them at once with the same commit, "atomically". This is the principle consideration as far as I can tell.
Like in your example, if each release of the frontend requires an equivalent release in the backend. With separate repos you have to coordinate multiple pull requests between repos. This takes effort and that effort multiplies the more projects you have that depend on each other. As opposed to having a single PR that contains changes for both which are guaranteed to be released at the same time with no additional coordination effort.
An API and frontend might not be a good example since APIs are typically designed to be versioned separately from any client*. But say you have some integration tests for your UI. Both code bases are tightly coupled; a trivial change in your UI will likely require an equivalent change in your tests. Regardless of language, conceptually they are meant to "change together" and therefore, its far easier to manage them when they are in the same repository. Similar to unit tests, though those are usually the same language at least.
Another issue with multiple repos is that code reviews that require cross cutting changes have a little more friction because you have to update multiple branches in multiple repositories. Especially when doing multiple rounds of review.
Deployments are affected as well, they will have to be carefully coordinated. Merging a PR in one repo and triggering a deployment, might break the other deployments because the other PRs haven't been approved yet. Alternatively you will have to write all your projects to be backwards compatible always.
Automation across multiple repositories can alleviate some of these problems, but usually it still requires some form of manual syncing.
Realistically, either path has tradeoffs, making the answer to this question a deeply unsatisfying "it depends". My rule of thumb is that code that changes together, lives together in the same repository. Only when the burdens of keeping it in the same repository outweigh the burdens of keeping them separate do I make the split.
Regarding mixing languages
Git is language agnostic so it doesn't care. Your other tooling might. You will have to weigh that against the above benefit.
Some CI/CD tools need extra configuration when the root of your repository is not the root of your project. I would consider that tool poorly designed if it can't support that extra configuration and I have not yet run into such a tool**.
For language specific tools like linters, etc, as long as each project is in it's own folder, they're not going to be aware of each other. Running these tools at the CI/CD level now may require an extra cd <subdirectory>
statement.
Your IDE might get confused when you open the project from the root. For example if you had a Python, C#, and Typescript in the same repo, one VSCode instance would have 3 "language servers" it would be communicating to, potentially 3 plugin UIs to hide and show depending on the file you're looking at, 3 places to pull debug configurations from and so on. So far in my experience, this only results in some minor configuration changes to workspace settings and otherwise everything works fine. Worst case I end up opening another instance VSCode per project which is what I'd be doing anyway if they were separate.
Teams play a role as well
This also touches on your team structure. If you have separate teams for each product, it might make sense to separate them because the cross team coordination needs to happen anyway because no one member commits in multiple repos.
I personally don't partition teams like this because I prefer teams that are able to write code in any part of the application system, front, back, side whatever. But I recognize this is not always desirable or possible.
Why does Google, Twitter, etc do it?
At Google scale, their projects' dependencies are probably developed by their own internal teams. I suspect this means that in any given piece of work, they're mostly making commits that affect many projects at once.
Since that was the default case for them they decided to put everything in the same repo. They incurred a significant cost in doing so but for them, it makes sense because cross cutting changes are the norm because of all these internally managed dependencies.
For typical projects, the dependencies are mostly projects managed by 3rd parties outside of the company. Think nuget and npm packages. And your other projects are largely independent from each other. So putting every project in a single repo by default doesn't make sense.
Overall, keep in mind, Google, Twitter, etc are all managing products they own and have total control over. Whereas your company may be developing multiple projects for different clients. In which case, you are facing challenges that Google does not despite how massive they are and Google has not considered those challenges in their solution.
Here is a self-proclaimed Google engineer discussing why they like the monorepo. It is a confirmation of the above.
Say I make a change to a commonly used library (let's say deprecating a function, and replacing it with another):
I can see literally every use of the old function.
I can run the tests for everyone who uses that function.
-
- this is automated; the build/test tooling can figure out the transitive set of build/test targets that are affected by such a
change.
I can (relatively) easily update every use of the deprecated call with the new hotness
I can do that all within the same commit (or set of commits, realistically)
None of this is impossible with multiple repos, it's just a lot more
difficult to coordinate
Asides
*In the case of an API and a frontend that uses that API. I would typically consider them independent and version them separately. An API should be designed to service many clients and not just one frontend. Otherwise a server side UI framework like ASPnet or PHP would be the more appropriate choice imo. I recognize though that this is often not the case and we have frontends tightly coupled into backends designed just for them.
**SonarQube in the distant past had issues with scanning repositories with multiple languages. So there is some precedent for important tools not being able to handle mixed language projects. Though that issue may have been before the project really took off. Certainly it was before I had heard about it.