SEO-friendly URLs

This post could probably go in the miscellaneous section. I am developing a directory website to service churches and religious organizations and am beginning to think about SEO and url creation.

The search results page url looks like this: www.site.com/profile/search?search=books

Each profile listing gets its own page, and I want the page url to be more user and seo friendly. I’m thinking about something like this:

www.site.com/organization-type/organization-name-city-state

or

www.site.com/organization-type/city-state/organization-name

I want to try to avoid having the profile id in the url, but recognize that including it would be the most full-proof way of avoiding any problems down the road with similar or duplicate organization names. My question is, should I go ahead and add the id in or keep it as above and use the org name, city, and state for the query parameters? Also, should I tack .html onto the end?

I have read some about mod_rewrite for url rewriting, but it seems like Yii url manager handles the rewriting just fine. Are there any performance or other advantages with one vs. the other?

Thanks for any insights.

Your idea of using SEO-friendly URLs like /organization-type/city-state/organization-name is great for both user experience and search engine visibility. Including the ID is optional, but recommended if you expect duplicate names, as it ensures uniqueness and avoids routing issues. Avoid using .html at the end it’s outdated and doesn’t add SEO value today. Yii’s URL Manager is sufficient; using mod_rewrite directly isn’t necessary unless you have very custom needs. Just make sure to handle slugs and special characters cleanly for consistency.

1 Like

Oh geez, okay, here goes — listen up, this is Morty talkin’, and I’m gonna try to explain this web URL stuff without totally messing it up, alright? So, you wanna make your church directory URLs all nice and shiny for humans and for those sneaky SEO bots that crawl your site like little spider-Ricks, right?

Here’s the deal: you definitely want the ID in your URL somewhere. I mean, otherwise, what if you got two churches called “St. Morty’s Church” in different towns? Your URL’s gonna get all confused, like me trying to remember which portal gun to use—total disaster! So putting the ID first, like organization/123-st-mortys-church-somewhere-ny is like giving the internet a GPS coordinate and a friendly name.

Now, about the .html thing — nah man, that’s like slapping a Doc Brown flux capacitor label on a spaceship that’s already flying. It’s kinda old school and doesn’t really help SEO or performance. Pretty URLs without extensions look cleaner and that’s what Google likes these days.

And about your URL rewriting question—Yii’s urlManager is like Rick’s portal gun for URLs: super optimized, and it handles the rewriting internally, so you don’t have to go messing with mod_rewrite at the Apache level unless you’re a masochist who likes pain. Plus, it keeps your app logic in one place and makes config tidier than Squanchy’s party room.

So here’s some cursed-but-effective code that uses slug behavior so your URLs get automatically cooked up from the organization’s name, city, and state and map them to IDs so everything’s unique and everything reroutes correctly if someone tries to mess with the slug.

Give this a shot:

config/web.php

'urlManager' => [
	'enablePrettyUrl' => true,
	'showScriptName' => false,
	'rules' => [
		'organization/<id:\d+>-<slug:[a-z0-9-]+>' => 'organization/view',
		'organization/<id:\d+>' => 'organization/view',
		'organization/<slug:[a-z0-9-]+>' => 'organization/view',
		'<controller>/<action>' => '<controller>/<action>',
	],
],

Model with SluggableBehavior so the slug updates from name, city, state

public function behaviors(): array
	{
		return [
			/**
			* Sluggable Behavior
			* @url https://www.yiiframework.com/doc/api/2.0/yii-behaviors-sluggablebehavior
			*/
			[
				'class' => SluggableBehavior::class,
				'attribute' => ['name', 'city', 'state'],// parts that make up the slug
				'slugAttribute' => 'slug',
				'ensureUnique' => true,
				'immutable' => false,// if you want slug to update on name change, set false; true otherwise
			],
		];
	}

Controller redirects to the canonical ID + slug URL so SEO is happy and no duplicate content confusion
namespace app\controllers;

public function actionView(?int $id = null, ?string $slug = null)
{
	$model = $this->findModel($id, $slug);
	
	if ($id !== null)
	{
		if ($slug !== $model->slug)
		{
			return $this->redirect(['view', 'id' => $id, 'slug' => $model->slug], 301);
		}
	}
	else
	{
		return $this->redirect(['view', 'id' => $model->id, 'slug' => $model->slug], 301);
	}
	
	return $this->render('view', ['model' => $model]);
}

Alright, so bottom line: keep the ID, slap on a friendly slug for humans, ditch that .html nonsense, and rely on Yii’s built-in URL magic. That’s the way to keep your URLs clean, unique, and totally SEO-awesome, Morty approved!

Wubba lubba URL dub dub!