How to create SEO friendly URLs with category/subcategories/article slug in angular project?
Do you literally just mean a link with link text that differs from its href, like this?
If so,
<a [routerLink]="url">{{seoUrl}}</a>
Typescript:
url: 'https://www.google.com';
seoUrl: 'https://www.google.com/category/slug';
Or do you want to do something more with the url of the page itself?
EDIT:
Routing module
// Declare two routes with an optional title. We will always redirect to the title route. Order matters here - routes will be matched in order.
{ path: 'category/:category/:title', component: CategoryComponent },
// this path declares a route similar to /category/abc where abc is a category
{ path: 'category/:category', component: CategoryComponent }
Category component
// component decorator omitted for brevity
export class CategoryComponent implements OnInit {
constructor(private route: ActivatedRoute,
private router: Router
) {
}
ngOnInit(): void {
// get the category from the url
const categoryName = this.route.snapshot.paramMap.get('category');
const titleName = this.route.snapshot.paramMap.get('title');
// TODO: implement categoryService
this.categoryService.getCategory(categoryName).subscribe(category => {
if (!title) {
this.router.navigateByUrl(`/category/${category.name}/${category.title}`);
return;
}
// TODO: render the category
});
}
}
How does Stack Overflow generate its SEO-friendly URLs?
Here's how we do it. Note that there are probably more edge conditions than you realize at first glance.
This is the second version, unrolled for 5x more performance (and yes, I benchmarked it). I figured I'd optimize it because this function can be called hundreds of times per page.
/// <summary>
/// Produces optional, URL-friendly version of a title, "like-this-one".
/// hand-tuned for speed, reflects performance refactoring contributed
/// by John Gietzen (user otac0n)
/// </summary>
public static string URLFriendly(string title)
{
if (title == null) return "";
const int maxlen = 80;
int len = title.Length;
bool prevdash = false;
var sb = new StringBuilder(len);
char c;
for (int i = 0; i < len; i++)
{
c = title[i];
if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9'))
{
sb.Append(c);
prevdash = false;
}
else if (c >= 'A' && c <= 'Z')
{
// tricky way to convert to lowercase
sb.Append((char)(c | 32));
prevdash = false;
}
else if (c == ' ' || c == ',' || c == '.' || c == '/' ||
c == '\\' || c == '-' || c == '_' || c == '=')
{
if (!prevdash && sb.Length > 0)
{
sb.Append('-');
prevdash = true;
}
}
else if ((int)c >= 128)
{
int prevlen = sb.Length;
sb.Append(RemapInternationalCharToAscii(c));
if (prevlen != sb.Length) prevdash = false;
}
if (i == maxlen) break;
}
if (prevdash)
return sb.ToString().Substring(0, sb.Length - 1);
else
return sb.ToString();
}
To see the previous version of the code this replaced (but is functionally equivalent to, and 5x faster), view revision history of this post (click the date link).
Also, the RemapInternationalCharToAscii
method source code can be found here.
Trying to make SEO friendly urls without using database
I'm assuming that you have a human readable category name (ex My Category) and you are converting that to a slug in your URLs (ex my-category).
A naive approach to doing this would be to attempt to reverse the slug and lookup the category by name, but there are use-cases where this won't work.
class CategoriesController extends Controller
{
public function index($slug)
{
$name = ucwords(str_replace('-', ' ', $slug));
$posts = Category::where('name', '=', $name)->first()->posts;
return view('index', compact('posts'));
}
}
The problem with that approach is there are cases where information is lost when converting the name to a slug, for example if the proper category name contains a hyphen, the hyphen becomes a space when converting the resulting slug.
You can approach this a different way, without storing the slug, by modifying your route:
Route::get('/categories/{category}/{slug}', 'CategoriesController@index')->name('category');
In this case, you pass both the ID and the slug in the URL. You can either fetch the category from the ID or use route model binding to fetch it automatically. This technically means you can pass any string as the slug and it will still work. You can handle this by determining the actual slug and redirecting to the canonical URL if the end user provides an incorrect slug.
class CategoriesController extends Controller
{
public function index(Category $category, $slug)
{
if(str_slug($category->name) != $slug) {
// Redirect to the canonical URL
}
$posts = $category->posts;
return view('index', compact('posts'));
}
}
A benefit of keeping both the ID and the slug in the URL is you get redirection for free: If the category name changes, the new URL will work and the old URL will automatically redirect to the new one.
Side note: If you look the URL for his question you'll notice this is the approach StackOverflow uses.
Adding a SEO friendly Url Slug in Dynamic Views of Angular UI-Router
Google has been attempting to make one page apps more SEO friendly, but not sure how far they have gotten, which is why I stick with a non one page app url structure when I need a site to be SEO friendly.
One way to accomplish this using your set up is to add to your config $locationProvider.html5Mode(true);
and add under your HTML header <base href="/app/" />
which will turn your url
www.website.com/app/#/browse/productId
to:
www.website.com/app/browse/productId
My issue with this set up I have found is that you need to configure your server to only output one entry point to your front end such as www.website.com/app. Here is a tutorial on setting this up.
Is is possible to make SEO friendly Url's in ASP.NET Core like this one
You can do this quite easily with attribute routing:
[Route("blogs")]
public class BlogController
{
[AcceptVerbs("GET", "HEAD", Route = "{slug}")]
public IActionResult View(string slug)
{
}
}
This maps all requests to /blogs/whatever
to that action, and sets slug
to the value after "/blogs/".
Codeigniter - SEO Friendly URL Structure (Slug Implementation)
How to use slug?
Will explain with an example:
URL - http://www.example.com/products/apple-iphone-5S-16GB-brand-new/
1) Assuming you are having a product page and ofcourse product page needs some data from URL to understand which product to display.
2) Before we were querying our database using the id we are getting from the URL. But now we'll do the same thing (querying our database) just replacing id with slug and thats it!
3) Hence adding an additional column in your database named slug. Below will be your updated product database structure (just an example).
Columns Values
id (int(11), PK) 1
title (varchar(1000)) Apple iPhone 5S 16GB
slug (varchar(1000)) apple-iphone-5S-16GB-brand-new
price (varchar(15)) 48000
thumbnail (varchar(255)) apple-iphone-5S-16GB-brand-new.jpg
description (text) blah blah
...
...
I've also answered on slug before. Check if it helps.
How to remove params from url codeigniter
Edit:
For this you have to do below changes -
1) Create below 2 tables
slug_table:
id (PK) | slug | category_id (FK)
category_table:
id (PK) | title | thumbnail | description
2) config/routes.php
$route['/(:any)'] = "category/index/$1";
3) models/category_model.php (create new file)
class Category_model extends CI_Model
{
public function __construct()
{
parent::__construct();
$this->db = $this->load->database('default',true);
}
public function get_slug($slug)
{
$query = $this->db->get_where('slug_table', array('slug' => $slug));
if($query->num_rows() > 0)
return $query->row();
return false;
}
public function get_category($id)
{
$query = $this->db->get_where('category_table', array('id' => $id));
if($query->num_rows() > 0)
return $query->row();
return false;
}
}
4) controllers/category.php (create new file)
class Category extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('category_model');
}
public function index($slug)
{
$sl = $this->category_model->get_slug($slug);
if($sl)
{
$data['category'] = $this->category_model->get_category($sl->category_id);
$this->load->view('category_detail', $data);
}
else
{
// 404 Page Not Found
}
}
}
5) views/category_detail.php (create new file)
<label>Category title: <?php echo $category->title; ?></label><br>
</label>Category description: <?php echo $category->description; ?></label>
Creating more SEO friendly urls in Django
You have left in your regular expressions when you just want to use the slug
path('(?P<slug>[-a-zA-Z0-9_]+)/', views.blog_details, name='blog-details'),
can simply be
path('<slug: slug>', views.blog_details, name='blog-details'),
see the docs for more
Related Topics
Getting Http Code in PHP Using Curl
Laravel Stylesheets and JavaScript Don't Load for Non-Base Routes
Generate Random 5 Characters String
Php7.1 JSON_Encode() Float Issue
How to Build a JSON Array from MySQL Database
PHP MySQL Update If Exist or Insert If Not
Any Decent PHP Parser Written in PHP
How to Write a Stored Procedure Using PHPmyadmin and How to Use It Through PHP
Best Way to Determine If a Url Is an Image in PHP
How to Use PHP to Check If a Directory Is Empty
How to Call a Closure That Is a Class Variable
How to Include PHP Files That Require an Absolute Path
How to Check and Set Max_Allowed_Packet MySQL Variable
Fatal Error: Maximum Execution Time of 300 Seconds Exceeded
How to Use Where in with Doctrine 2
How Send Message Facebook Friend Through Graph API Using Accessstoken