{"id":20046205,"url":"https://github.com/spa5k/slugify-postgres","last_synced_at":"2026-02-27T22:42:05.514Z","repository":{"id":104841990,"uuid":"489099864","full_name":"spa5k/slugify-postgres","owner":"spa5k","description":"PostgreSQL Extension to generate various variant of Slugs from a string.","archived":false,"fork":false,"pushed_at":"2022-05-07T14:15:44.000Z","size":7,"stargazers_count":9,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-08-10T21:14:50.633Z","etag":null,"topics":["postgresql","postgresql-extension","rust","slugify"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/spa5k.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-05-05T19:21:39.000Z","updated_at":"2025-05-20T14:56:38.000Z","dependencies_parsed_at":"2023-05-07T07:00:34.543Z","dependency_job_id":null,"html_url":"https://github.com/spa5k/slugify-postgres","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/spa5k/slugify-postgres","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spa5k%2Fslugify-postgres","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spa5k%2Fslugify-postgres/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spa5k%2Fslugify-postgres/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spa5k%2Fslugify-postgres/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/spa5k","download_url":"https://codeload.github.com/spa5k/slugify-postgres/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spa5k%2Fslugify-postgres/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29917935,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-27T19:37:42.220Z","status":"ssl_error","status_checked_at":"2026-02-27T19:37:41.463Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["postgresql","postgresql-extension","rust","slugify"],"created_at":"2024-11-13T11:21:59.697Z","updated_at":"2026-02-27T22:42:05.499Z","avatar_url":"https://github.com/spa5k.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"## PostgreSQL Extension to generate various variant of Slugs from a string.\n  \n\n##  1. Installation\n\n### 1.1. Installation on non docker environment\n\n#### 1.1.1. Install rust through rustup.\n  \n  ```bash\ncurl https://sh.rustup.rs -sSf | sh\n  ```\n#### 1.1.2. Prepare your postgres installation\n#### 1.1.3. Install pgx\n  \n  ```bash\ncargo install cargo-pgx\n  ```\n#### 1.1.4. Initialize pgx for the postgres version you have already installed\n    \n- Note: Handle the number accordingly.\n```bash\ncargo pgx init --pg14 $(which pg_config)\n```\n#### 1.1.5. Install the extension\n    \n```bash\ngit clone https://github.com/spa5k/slugify-postgres \\\n\u0026\u0026 cd slugify-postgres \\\n\u0026\u0026 cargo pgx install\n```\n\n### 1.2. Installation on docker environment\n\n  Check the included [Dockerfile](./docker/Dockerfile) for the installation template.\n\n##  2. Functions available\n\n### 2.1. Enable the extension\n  \n```sql\nCREATE EXTENSION IF NOT EXISTS slugify;\n```\n\n###  2.2. Slug -\n\n\n#### 2.2.1. Generate Slug\n\n  \n\n```sql\n\nselect slug('hello world');\n\n-- hello-world\n\n-----------------------------\n\nselect slug('Æúű--cool?');\n\n-- aeuu-cool\n\n-----------------------------\n\nselect slug('jaja---lol-méméméoo--a');\n\n-- jaja-lol-mememeoo-a\n\n-----------------------------\n```\n\u003e It even supports unicode characters.\n```sql\nselect slug('影師嗎');\n\n-- ying-shi-ma\n\n```\n\n#### 2.2.2. Generate slug with random suffix.\n\n\u003e Note - rand by default adds a 5 character random suffix. and add it to parent string using the separator that is used, else the default separator if none is mentioned.\n\n\u003e These slugs are generated by appending a string generated through [nanoid](https://github.com/ai/nanoid)  with length of 5 as default, you can also change the length.\n\n\n```sql\n\nselect slug_rand('Компьютер');\n\n-- komp-iuter-lkai\n\n-----------------------------\n\nselect slug_rand('Æúű--cool?');\n\n-- aeuu-cool-3epv\n\n-----------------------------\n\n```\n\n  \n\n###  2.3. Slug with different separator -\n\n  \n\n#### 2.3.1. Generate a slug with different separator.\n\n  \n\n```sql\n\nselect slug_sep('hello world', '_');\n\n-----------------------------\n\n-- hello_world\n\nselect slug_sep('Of course can be paid','*');\n\n-----------------------------\n\n-- of*course*can*be*paid\n\n```\n\n  \n\n#### 2.3.2. Generate a slug with different separator and random suffix.\n\n  \n\n```sql\n\nselect slug_rand_sep('heLLo WorlD','_');\n\n-- hello_world_obc5\n\n-----------------------------\n\nselect slug_rand_sep('Of course can be paid','*');\n\n-- of*course*can*be*paid*3ibd\n\n-----------------------------\n```\n\n\n###  2.4. Custom Length of random  suffix-\n\n  \n\n#### 2.4.1. Generate a slug with custom length of random suffix.\n\n  \n\n```sql\n\nselect slug_rand_c('the 101 dalmatians', 10);\n\n\n-- the-101-dalmatians-mrjygfcnr\n\n-----------------------------\n```\n\n  \n\n#### 2.4.2. Generate a slug with custom length of random suffix and custom separator.\n\n  \n\n```sql\n\nselect slug_rand_sep_c('the 101 dalmatians', '_',10);\n\n-- the_101_dalmatians_5en4hhnrt\n\n-----------------------------\n```\n\n## 3. Add the trigger.\n\n\u003e Typically you will only want to create a slug when a record is created. If you update the title of something, you probably want to preserve the slug as it may well be part of your websites’ URL structure. You could update your slug each time, but you’d need an audit table to redirect people from the previous slug(s) to the new ones.\n\n\u003e Depending on your schema, you can have a function and trigger for each table that requires a slug, OR if you have consistent column names over tables you can create a generic function that faithfully assumes you’ve got a title and a slug column:\n\n\n```sql\nCREATE FUNCTION public.set_slug_from_title() RETURNS trigger\n    LANGUAGE plpgsql\n    AS $$\nBEGIN\n  NEW.slug := slug(NEW.title);\n  RETURN NEW;\nEND\n$$;\n```\n\n\u003e This function returns a trigger, whilst the slugify function returns text. The NEW keyword above is effectively referencing the table row we are updating.\n\n\u003eNote that the above function will happily generate duplicate slugs. You could append an ID, hashid or some other bit of random text to shoot for uniqueness.\n\n\u003e And finally, to add this trigger to your table(s)…\n\n```sql\nCREATE TRIGGER \"slugify_the_name\" BEFORE INSERT ON \"table_name\" FOR EACH ROW WHEN (NEW.title IS NOT NULL AND NEW.slug IS NULL)\nEXECUTE PROCEDURE set_slug_from_title();\n```\n\n## 4. More usecases\n\u003e Please check the tests below for more possible usecases.\n\n```rust\nassert_eq!(\"hello-world\", slug(\"hello world\"));\nassert_eq!(\"hello_world\", slug_sep(\"hello world\", \"_\"));\nassert_eq!(\"helloworld\", slug_sep(\"hello world\", \"\"));\nassert_eq!(\"hello%world\", slug_sep(\"hello world\", \"%%\"));\nassert_eq!(slug(\"alice@bob.com\"), \"alice-bob-com\");\nassert_eq!(slug(\"alice@bob.com\"), \"alice-bob-com\");\nassert_eq!(slug(\"10 amazing secrets\"), \"10-amazing-secrets\");\nassert_eq!(slug(\"the 101 dalmatians\"), \"the-101-dalmatians\");\nassert_eq!(\n    slug_rand(\"the 101 dalmatians\").len(),\n    \"the-101-dalmatians\".len() + 5\n);\nassert_eq!(\n    slug_rand_c(\"the 101 dalmatians\", 10).len(),\n    \"the-101-dalmatians\".len() + 10\n);\nassert_eq!(\n    slug_rand_sep_c(\"the 101 dalmatians\", \"_\", 10).len(),\n    \"the-101-dalmatians\".len() + 10\n);\nassert_eq!(slug(\"lucky number 7\"), \"lucky-number-7\");\nassert_eq!(\n    slug(\"1000 reasons you are #1\"),\n    \"1000-reasons-you-are-1\"\n);\nassert_eq!(slug_sep(\"hello world\", \".\"), \"hello.world\");\nassert_eq!(slug_sep(\"hello world\", \"_\"), \"hello_world\");\nassert_eq!(\n    slug_rand_sep(\"hello world-\", \"_\").len(),\n    \"hello_world\".len() + 5\n);\nassert_eq!(slug(\"影師嗎\"), \"ying-shi-ma\");\nassert_eq!(slug(\"Æúű--cool?\"), \"aeuu-cool\");\nassert_eq!(\n    slug(\"Nín hǎo. Wǒ shì zhōng guó rén\"),\n    \"nin-hao-wo-shi-zhong-guo-ren\"\n);\nassert_eq!(slug(\"jaja---lol-méméméoo--a\"), \"jaja-lol-mememeoo-a\");\nassert_eq!(slug(\"Компьютер\"), \"komp-iuter\");\nassert_eq!(slug(\"Компьютер\"), \"komp-iuter\");\nassert_eq!(slug_sep(\"hello world\", \"-\"), \"hello-world\");\nassert_eq!(slug_sep(\"hello world\", \" \"), \"hello world\");\nassert_eq!(\n    \"hello-world\".len() + 5,\n    slug_rand(\"hello world\").len()\n);\nassert_eq!(\n    \"hello_world\".len() + 5,\n    slug_rand_sep(\"hello world\", \"_\").len()\n);\n```\n\n\n## 5. Acknowledgements\n\n### 5.1. [@kez](https://www.kdobson.net/2019/ultimate-postgresql-slug-function/)\n### 5.2. [@slugify-rs](https://github.com/spa5k/slugify-rs)\n### 5.3. [@pgx](https://github.com/tcdi/pgx)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspa5k%2Fslugify-postgres","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspa5k%2Fslugify-postgres","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspa5k%2Fslugify-postgres/lists"}