DEV Community

Cover image for Create slug using title in React
Deepak Jaiswal
Deepak Jaiswal

Posted on

2 1 2 1 1

Create slug using title in React

I have seen some time we are using _id in routing. and we get the data based on _id but it shows our original data id that i have leak. and based on SEO the id is not best way to add in url.

Like i'm creating a blog detail page based on id it looks bad but when i am using slug based on title. it looks good.

And the user understand by the url.

function getSafeRegexpString(input) {
  return input
    .split("")
    .map((char) => `\\${char}`)
    .join("");
}
Enter fullscreen mode Exit fullscreen mode

I am using the package diacritics which is remove unnecessary text.

import { remove as stripAccents} from 'diacritics';
function format(
  input,
  delimiter,
  ignoreInvalid = false
) {
  const harmonized = stripAccents(input).trim().toLowerCase();
  const safeDelimiter = getSafeRegexpString(delimiter);

  if (ignoreInvalid) {
    return harmonized.replace(/\s+/g, delimiter);
  }

  return harmonized
    .replace(new RegExp(`[^a-z0-9\\u0900-\\u097F${safeDelimiter}]+`, "g"), delimiter) // Replace all non-valid caracters by delimiter
    .replace(new RegExp(`${safeDelimiter}+`, "g"), delimiter) // Remove multiple delimiters repetition
    .replace(new RegExp(`^${safeDelimiter}`, "g"), "") // remove delimiter at the beginning
    .replace(new RegExp(`${safeDelimiter}$`, "g"), ""); // remove delimiter at the end
};
Enter fullscreen mode Exit fullscreen mode

You can also put your regex for custom change. I have put [^a-z0-9\u0900-\u097F${safeDelimiter}] for hindi words.

export default function slugify(
  node,
  options = { delimiter: "-", prefix: "" }
) {
  if (!options.delimiter) options.delimiter = "-";
  if (!options.prefix) options.prefix = "";

  if (!node || typeof node === "boolean") {
    return "";
  }

  const { delimiter, prefix } = options;

  // boolean
  if (typeof node === "boolean") {
    return ""; // not much we can do here
  }

  // string, number
  if (typeof node === "string" || typeof node === "number") {
    const harmonizedPrefix = format(prefix, delimiter, true);
    const harmonizedNode = format(String(node), delimiter);

    if (harmonizedPrefix) {
      return `${harmonizedPrefix}${delimiter}${harmonizedNode}`;
    }

    return harmonizedNode;
  }

  // ReactPortal
  if ("children" in node) {
    return slugify(node.children);
  }

  // ReactElement
  if ("type" in node) return slugify(node.props.children, options);

  // ReactFragment (including array of nodes)
  if (Symbol.iterator in node) {
    return slugify(
      Array.from(node)
        .map((subNode) => slugify(subNode, { delimiter }))
        .join(delimiter),
      options
    );
  }

  // unhandled case
  return "";
};
Enter fullscreen mode Exit fullscreen mode

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay