Best way to generate url-friendly unique slug for document

What is the best way to generate a unique, readable slug for a document? Say you want to use it as a route like myapp.com/my-blog--post. Is there a shortcut to doing this using builtin FQL functions? In my case the document has a title so I was thinking of doing a combination of title with spaces replaced by hyphens and special characters removed and then concatenating a hash of the ref ID, does that make sense?

1 Like

To get a unique short string based on an ID generated by Fauna you could lookup a utility I made some time ago: https://github.com/gahabeen/nanohash.

Let me know if you need help.

2 Likes

Or https://github.com/ai/nanoid

2 Likes

Just getting back to this. NanoID seems a bit overkill. I’ll explain what I would like to do using an example:

Medium post URLs look like this: https://debugger.medium.com/why-is-apples-m1-chip-so-fast-3262b158cba2. Notice the string added to end of what seems to be just the post’s title with spaces replaced with hyphens. This is what I would like to do in my app to generate SEO and user friendly shareable links. What I thought of doing is generating the string inside the document creation UDF, by taking the title string, replacing/removing special characters, and adding a short hash to end of it to avoid collisions. The question is, how to generate the hash? I know that the document ID would be perfect, but it’s a bit long (18 chars if I’m not mistaken) and I’m not sure if it’s wise to put the document ID in the url. I thought of maybe hashing the document ID with something that generates a short hash, maybe 4-6 chars, but not sure what to go for, this topic is a bit over my head.

alright I just naively remembered I can’t use javascript functions in my UDF statements when I tried doing this (where slugify is a util js function I wrote that replaces special chars):

friendlyUrl: slugify(Select(['data', 'message'], Var('newList'))) + '-' + Select(['ref', 'id'], Var('newList')),

and getting friendlyUrl: "object-object-[object Object]" when I update the function…

This leads me to another, more pressing question. How do you generate fields based on other fields of the same document at creation time???

I use the Let function to manipulate fields based on other fields. You can store the data from a given field on a key in Let and then use that key as a variable in the function Var.

For what you’re trying to do, I would separate the javascript logic and use the fauna javascript client. That way you can use your slugify function or any custom javascript logic and then send the final manipulated data back to fauna by running your javascript script in a node environment.

Or if you want more of an automated setup instead of having to run your node script each time and you are deployed through something like AWS lambda, you can have your slugify function run in a lambda function on the data you get back from fauna and then send the modified data back to fauna if you need the modified data stored in the database.

You should be able to do this with FQL. Try something like this:
LowerCase(ReplaceStrRegex("Foo Bar_FooBar", "(\\s|_)", "-")) => "foo-bar-foobar"

I just added a Slugify function to faunadb-fql-lib: https://www.npmjs.com/package/faunadb-fql-lib

1 Like

@AB_pnc There should not be an issue using the ref id in the URL. That is if you mean “secure” when you said “wise”, no it shouldn’t matter. security comes from the security system.

https://forums.fauna.com/t/ref-predictability/194/5?u=ptpaterson