<@U0RQY0KK5> I worked up a better version of my sl...
# prisma-whats-new
m
@nilan I worked up a better version of my slug function that checks for existing slugs and adds a dash and an integer to the new slug. Right now it’s kind of specific to my project (because it has a query, and uses graphql-request so has a PAT. Let me know if you think it’s worth sharing and you want to take a crack at abstracting it for others to use.
a
@mwickett @nilan it might be a good idea to abstract this away from the user and create a Type for it, that way unique check could also be done server-side like with
ID
m
This is for generating a slug for an entry (Blog post, article, etc. - any collection item with a title)
Definitely open to other ways of doing it.
a
I understand, but it would be nice to have graphcool create a field Type for it, so you can just add it to your schema and the server will take care of it, that's what I meant.
m
Gotcha.
Yes, it would be!
a
Copy code
type Blog implements Node {
    id: ID!
    title: String!
    slug: Slug! @basedOn(field: 'title') @isUnique
}
👍 1
m
…and I just found a problem with it. hah.
a
Do you have a github account? Then I can reference you https://github.com/graphcool/feature-requests/issues/311
m
Yep - same as here, mwickett
a
updated it 🙂
What's the problem with the code?
m
Great. Saw the notification.
Realized I need to change my query to filter for the slug, so that if there is more than one item with same slug it will return multiple results.
a
And why don't you query _allJobsMeta(filter: { slug: $slug }) { count }
m
Simple, I didn’t know I could!
a
with
const count = data._allJobsMeta.count
m
yup
Way simpler.
Thank you
a
More readable
no problem
m
I love learning, thanks for sharing that.
👍🏻 1
a
To get back to your earlier statement, how would you get >1 existing node with the same slug, if you check for uniqueness like this?
m
No, you’re right - it’d be impossible.
It only works the way you suggest.
a
Well, it wouldn't always.
If you delete the original item (the one with the slug without suffix)
This would fail
So I would suggest:
{ filter: { slug_starts_with: $slug } }
Because if you have
my-title
and
my-title-1
, delete
my-title
, and query for exact match on slug, the count will always be 0
m
Right
a
Even if you use my query, you still wouldn't know anything
because even if the exact match gives you count: 1
You still don't know how many
my-title-...
you have
m
Yeah. Man. I didn’t know you could do
slug_starts_with
either. I have a lot to learn.
a
So it will only work with starts_with. Also with your original query you had that issue
So the correct one is:
Copy code
query ($slug: String!) {
   _allJobsMeta(filter: { slug_starts_with: $slug }) {
      count
   }
}
Which is still wrong, thinking about it
Damn...
If you had
my-title
,
my-title-1
,
my-title-2
,
my-title-3
, and you delete
my-title
and
my-title-1
, the count would be 2, and you would create a duplicate
my-title-2
slug again
m
Damn
Yeah
argh. slugs
Your suggestion about a Type is even better now
Sorry to drag you into this, didn’t mean to 🙂
a
take allJobs instead of meta, filter by starts_with $slug, orderby slug descending, take:1
that will give you the latest slug
m
Right - then grab that trailing integer and +1
a
yes
Copy code
query ($slug: String!)
{
  allJobs(filter: { slug_starts_with: $slug}, 
    orderBy: slug_DESC, first: 1)
  {
    slug
  }
}
m
So if it doesn’t exist, handle the
allJobs.length === 0
, otherwise split the trailing integer and increment
a
test that query, I don't know if first:1 returns a null value, or no value
m
Copy code
{
  "data": {
    "allJobs": []
  }
}
If the slug doesn’t exist
a
Only nasty thing is that
data.allJobs.split('-').pop()
won't work on the original slug
m
That should be ok - only need to do it if there is a slug that gets returned
a
so you have a
my-title
and you want to add another
my-title
m
right
a
the query would return
my-title
so no integer last part...
m
And you’d get ‘title’
parseInt ?
Returns
NaN
if it’s a String
so that could work
a
Yes, but it's slow
data.allJobs.slug[0].split('-').length == slug.split('-').length
?
m
Interesting
a
Last part of a slug could be an integer if the field that the slug is based on ends with integer right?
m
Yes
a
So parseInt would be wrong
m
yup
a
Lol
m
oh boy
slugs
Who knew they were so complicated
a
Gotta love 'm
m
Maybe I need a better approach for differentiating duplicates
Rather than just an incrementing integer
Put a small random string at the end? Trying not to make things to gross in terms of a URL
For our use case, the the chance of something ending in an integer is extremely low
a
that's how graphcool docs website works, check out the URL's
m
Not that it couldn’t happen
Yeah
I noticed 🙂
a
Copy code
(data.allJobs.length == 0 ? slug : (data.allJobs[0].split('-').length == slug.split('-').length ? `${slug}-1` : `${slug}${data.allJobs[0].split('-').pop() + 1}`))
m
That’s tight
a
that's awful...
m
I hadn’t gotten to reducing it to ternaries yet
lol
a
😃
this would work on
my-series-part-1
too 😄
m
True
I have to go check on the family, thanks for working through this and sharing so much, really appreciate it.
👍🏻 1
a
It's 3:22 am here, I'm calling it a day too 🙂 good luck with it 🙂
And btw, I would remove the code snippet, because it's in general, and we figured out it's not working correctly. Before anyone copies it and runs into the same trouble...
m
Good call - done!
n
thanks for your thoughts @mwickett and @agartha I'll take a closer look at the FR later today
👍🏻 1
side comment about GC docs slugs - they are generated "client side" using
pwgen -A -10 -1
😛
a
How do you deal with SEO with the slug suffix?
n
what do you mean?
a
Does the SEO of the docs website suffer from the fact that URL's end with the random alias suffix?
n
not that I'm aware of but that might actually be the case
tutsplus does it as well
a
Can't find a proper resource on it. I do read that when your page is also accessible by 'alias' alone, you should put a canonical link in there to point to the 'long' url, because having more than one url for a page hurts SEO. Can't find anything about whether
<http://mysite/c3vn8x/this-is-the-title>
is better than
<http://mysite/this-is-the-title-c3vn8x>
n
we return the "resource has moved" HTTP status code if you access https://graph.cool/docs/-aizoong9ah for example
a
That has the same positive effect on SEO