Fork me on GitHub
John Bradens02:08:40

I'm learning how to make web apps right now and I have a question. My goal is to make a user generated content website/app, like quora for example. I see tutorials for single page applications, but I'm thinking it might make more sense for me to have separate webpages for posts, so that it's easier for SEO. If I make a SPA, will the posts be found by google? If not, is it better to not do SPA? Does this mean I would technically be making a website and not a web-app? Thanks in advance.

John Bradens02:08:09

I think if I go the not-SPA route, it'll be helpful to use Compojure right? Thanks again if you have any thoughts on all this. I'm a little confused about the blurring of what things should be in back end vs front end after learning about SPA's

Rowan Barnard03:08:58

I'm learning this also at the moment; I think mostly SPAs are recommended unless you have a very simple site, like say a site selling a single or few products and services where you have just a relatively small number of static pages like home page, FAQ page, about page and so on. Most of the development in web frameworks seems to focus on SPAs now (I could be wrong though, this is just how it seems to my perception). SEO is more challenging for SPAs than static sites but it can be done and as it says on the bottom of this page, the user experience of an SPA is also important for achieving a high search ranking:

John Bradens03:08:55

Thanks for your reply! It sounds like I'll probably want to focus on SPAs then and I'll look at the resource you linked to see how to resolve the SEO challenges.

Rowan Barnard03:08:33

You're welcome and yes, it seems quora itself is an SPA so if you are planning something along similar lines then probably best to follow an established example. That link was just something I found with a quick google search so there may be better resources out there on how to resolve the issues, just so you know. But it's a starting point at least ;)

John Bradens04:08:34

Awesome, that's great to know about quora. Especially because they show up strongly in search results. Lots to learn! Thanks again šŸ™‚

Rowan Barnard04:08:12

No worries šŸ˜‰


SPA do make it harder to have good SEO. You need special care in designing your URLs, and in using server side rendering.

John Bradens04:08:44

Thanks @U0K064KQV, any advice or resources on how to design my URLs & do server side rendering?


I feel as a beginner, an MPA is an easier starting place. I would also say you need to ask yourself what kind of website you're making. Is it content focused, where articles are posted and read. Those are best as an MPA. But if it will be more like an app, where people are expected to interact a lot with it in a dynamic way, that's when an SPA is better.

šŸ’Æ 6

Also, for SPAs, SEO might not matter as much, like Quora is trying really hard to actually block the content and hide it behind a login, that drives people to signup and become more engaged, and also pushes them to their native app instead, which will again entrench them more so, as people will start going directly to Quora and not through Google.


So if you've decided you need to offer a lot of dynamic functionality and also need good SEO. Well, I think using Rum might be simplest: as it has SSR support. What a lot of people do is they use Node.JS in the server along their backend to render their front-end for first page load, or if the user is a search engine crawler. It's non-trivial to setup, and I'm not sure of any good resource on it. This is what I think people do with Reagent. I think Fulcro also has support for SSR.

Rowan Barnard05:08:31

So the Node,JS would sit alongside the JVM backend? Or you mean the Node,JS is the sole backend? Could you then run ClojureScript on the Node.JS backend in that case? Just wondering.

John Bradens05:08:09

Thanks @U0K064KQV for your detailed response! I will have to look more into MPA. My app is more content focused. Users will basically just create accounts, posts, comments etc. That's very interesting information about quora. Early on, I'm planning to use SEO to help get the app discovered. Later though, I might be more focused on boosting sign ups & getting people to use the app directly instead of from a different platform. You've given me a lot to think about.

John Bradens05:08:31

I'll look into Rum for SSR. The Node.js might be a little over my head right now, but I appreciate knowing about it. I've done a few tutorials with Reagent so I will revisit those & look into fulcro too. I'll probably be back here asking more questions soon šŸ™‚ Thanks again for all the info!


Well, you could go with NodeJS backend as well. But most people go with Clojure backend and use Node to prerender the front-end. So for example Reagent has a render-to-string function, so they will run their ClojureScript code on the server using Node and call this function to render the page to a string, and either save that string to a file if the page doesn't change, or they'd serve it back to the client and run it through Node at runtime from the server.


So ya, NodeJS would sit alongside the backend.


And for URL design, not sure of a good resource either. But basically each URL should map to a logical piece of content, and if I were to bookmark the URL and come back to it later I should see the same logical content that when I bookmarked it. And you'll want to use the History API so when you navigate the APP, the real browser URL changes along with it.

Rowan Barnard05:08:20

Thanks Didibus, this helps clarify things for me too šŸ™‚


Like I said haha this stuff is not super easy. I feel starting with an MPA, adding some dynamism to it with a bit of JS is probably an easier place to start. Or try for an SPA, but maybe don't worry about SEO for now haha.

šŸ‘ 3

No worries. Hope I helped

John Bradens05:08:53

Very interesting. This is VERY helpful! Thanks again.


The technique you might be looking for is called hydration in the react world.

šŸ‘ 6
Franco Gasperino04:08:46

Input on a route using available core functions to accomplish the following: ā€¢ Given a timeout, attempt to write a sequence of values to a channel. ā€¢ If any values are not written to the channel before the timeout expires, return the remaining sequence.

(defn enqueue [channel values]
    (let [timeout (clojure.core.async/timeout 1000)]
      (loop [coll values]
        (if-let [current (first coll)]
          (let [[v p] (clojure.core.async/alts!! [[channel current] timeout])]
              (= timeout p)
              {:completed? false :remaining (into [] coll)}
              :default (recur (next coll))))
          {:completed? true}))))

(enqueue (clojure.core.async/chan 5) [1 2 3 4 5]) => {:completed? true}
(enqueue (clojure.core.async/chan 5) [1 2 3 4 5 6]) => {:completed? false, :remaining [6]}

Franco Gasperino04:08:22

I have gotten close with onto-chan!!, a timeout, and alts!!, but am unable to see what remains of the collection when the timeout is reached


anyone tried to make 4clojure with the gitpod repo of pez and if so, did you like it ?


i had it working last night, it works really well


I found it a bit confusing as to what it wanted sometimes with the (def __ :tests-fail) on each problem. So I mostly just deleted that each time and wrote a defn, I don't know what it actually wants me to write.


Maybe it wants a (def foo (fn [])) ?


@qmstuart Per the original 4clojure, it was "fill in the blank", indicated by __ in the tests you had to pass. Sometimes that __ was a value, most times it was a function. In Rich4Clojure, you can mostly just replace :tests-fail in that (def __ ...) with a value or function to make the tests pass (a few are more subtle than that -- the original 4clojure let you enter multiple forms in the input box so __ was not a single Clojure value but several in a row -- I think that only accounts for a handful of all the problems though.


Is there some select-keys-like thing where I can use regex to specify the keys I want?


nothing like that in clojure.core but it is easy to write your own function using reduce-kv


What about selecting keys while ignoring their namespace? Is there something like that in core?


(defn select-keys-by-pred [m pred]
    (fn [acc k v]
      (cond-> acc
        (pred k) (assoc k v)))

(select-keys-by-pred {"qwe" 1 "qrty" 2 "asd" 3} #(clojure.string/starts-with? % "q"))

šŸ™Œ 3

> What about selecting keys while ignoring their namespace? Is there something like that in core? no, but as I said it is trivial to implement.


look at the implementation I posted. pred is a predicate that suppose to validate the key and if the result is truthy - that key will be selected


Ok, clear enough. Thanks @U04V4KLKC.


medley.core is an awesome utility library with functions like these. filter-keys will do what you want.

šŸ‘ 3

using others from that API have saved me a lot of time