کاربران را به برنامه خود دعوت کنید

یکی از م effectiveثرترین روش ها برای جلب کاربران جدید برای نصب برنامه این است که کاربران خود را قادر به اشتراک گذاری مطالب برنامه خود با دوستان خود کنید. با استفاده از پیوندهای پویا ، می توانید یک تجربه اشتراک گذاری عالی بین کاربر ایجاد کنید: کاربرانی که توصیه های محتوا را از دوستان خود دریافت می کنند ، می توانند روی پیوند کلیک کرده و مستقیماً به محتوای به اشتراک گذاشته شده در برنامه شما منتقل شوند ، حتی اگر مجبور باشند به برنامه مراجعه کنند. فروشگاه یا Google Play Store را نصب کنید تا ابتدا برنامه خود را نصب کنید.

با ترکیب چسبندگی ارجاعات کاربر و تداوم پیوندهای پویا ، می توانید ویژگی های اشتراک گذاری و ارجاع کاربر به کاربر را ایجاد کنید که با جذب مستقیم کاربران به محتوای برنامه یا ارائه تبلیغاتی که متقابلاً به نفع ارجاع دهنده و ارجاع شده است ، کاربران جدیدی را به ارمغان می آورد. به

مزایای کلیدی

  • کاربران جدیدی که برای اولین بار برنامه شما را باز می کنند ، یک تجربه اجرا شخصی سفارشی را دریافت می کنند که بر اساس آنچه دوست آنها می خواست با آنها به اشتراک بگذارد ، زمینه سازی شده است. به عنوان مثال ، می توانید محتوایی را که با آنها به اشتراک گذاشته شده است نمایش دهید ، یا آنها را به طور خودکار با دوست دعوت کننده متصل کنید.
  • به اشتراک گذاشتن محتوا با دوستان در سراسر سیستم عامل ها برای دوستان آسان است ، خواه دوستان آنها برنامه شما را نصب کرده باشند یا نه.

در اینجا نحوه شروع کار آمده است!

راه اندازی یک پروژه جدید فایربیس و نصب پویا لینک SDK را به برنامه خود را.

نصب پیوندهای پویا SDK به Firebase اجازه می دهد تا اطلاعات مربوط به Dynamic Link را به برنامه منتقل کند ، از جمله پس از نصب برنامه توسط کاربر.

اکنون زمان تنظیم پیوندهایی است که کاربران می توانند برای دوستان خود ارسال کنند. اگر دوستان کاربران شما هنوز برنامه را نصب نکرده اند نگران نباشید. پیوندهای پویا می توانند این کار را برای شما انجام دهند.

برای هر عنصر از محتوای شما می خواهید به اشتراک گذاری، ایجاد یک پیوند پویا .

هنگامی که شما در پیوند پویا ایجاد میکنید، نیاز به ارائه یک HTTP یا HTTPS آدرس را به عنوان link پارامتر است که استفاده می شود برای شناسایی محتوای شما به اشتراک گذاری است. اگر وب سایتی با محتوای معادل دارید ، باید از آدرس وب سایت خود استفاده کنید. این امر باعث می شود که این پیوندها در بستری که از پیوندهای پویا پشتیبانی نمی کند ، مانند مرورگر دسکتاپ ، به درستی ارائه شوند. به عنوان مثال:

https://example.page.link/?link=https://www.example.com/content?item%3D1234&apn=com.example.android&ibi=com.example.ios&isi=12345

همچنین می توانید با افزودن پارامترهای رمزگذاری شده URL ، اطلاعات اضافی را به حجم بار داده ها اضافه کنید-برای مثال ، نشان دهید که پیوند برای کاربر خاصی در نظر گرفته شده است ، مانند دعوت نامه بازی.

https://example.page.link/?link=https://www.example.com/invitation?gameid%3D1234%26referrer%3D555&apn=com.example.android&ibi=com.example.ios&isi=12345

قبل از اینکه شما این لینک ها به اشتراک بگذارید، شما ممکن است مایل به استفاده از روغن ترد API فایربیس پویا لینک URL به URL های دوستانه، به دنبال. کوتاه به نظر می رسد پیوند پویا مانند مثال زیر:

https://example.page.link/WXYZ

هر کدام از لینک استفاده می کنید، هنگامی که کاربران باز کردن پیوند پویا بر روی دستگاه خود، برنامه های مشخص شده توسط apn پارامتر (بر روی آندروید) یا ibi و isi پارامترهای (در IOS) کاربران به فروشگاه بازی و یا برنامه فروشگاه به نصب برنامه اگر قبلاً نصب نشده است سپس ، هنگامی که برنامه نصب و باز می شود ، URL مشخص شده در پارامتر "پیوند" به برنامه منتقل می شود.

ابتدا نگاهی به این مثال ساده از یک برنامه چت مبتنی بر اتاق مانند Hangouts بیاندازید که پیوندهایی برای دعوت افراد به اتاق چت ایجاد می کند.

iOS

chat app screenshotchat app screenshot with share sheet

اندروید

chat app screenshotchat app screenshot with share sheet

سریع

func generateContentLink() -> URL {
  let baseURL = URL(string: "https://your-custom-name.page.link")!
  let domain = "https://your-app.page.link"
  let linkBuilder = DynamicLinkComponents(link: baseURL, domainURIPrefix: domain)
  linkBuilder?.iOSParameters = DynamicLinkIOSParameters(bundleID: "com.your.bundleID")
  linkBuilder?.androidParameters =
      DynamicLinkAndroidParameters(packageName: "com.your.packageName")


  // Fall back to the base url if we can't generate a dynamic link.
  return linkBuilder?.link ?? baseURL
}

هدف-ج

- (NSURL *)generateContentLink {
  NSURL *baseURL = [NSURL URLWithString:@"https://your-custom-name.page.link"];
  NSString *domain = @"https://your-app.page.link";
  FIRDynamicLinkComponents *builder = [[FIRDynamicLinkComponents alloc] initWithLink:baseURL domainURIPrefix:domain];
  builder.iOSParameters = [FIRDynamicLinkIOSParameters parametersWithBundleID:@"com.your.bundleID"];
  builder.androidParameters = [FIRDynamicLinkAndroidParameters parametersWithPackageName:@"com.your.packageName"];

  // Fall back to the base url if we can't generate a dynamic link.
  return builder.link ?: baseURL;
}

جاوا

public static Uri generateContentLink() {
    Uri baseUrl = Uri.parse("https://your-custom-name.page.link");
    String domain = "https://your-app.page.link";

    DynamicLink link = FirebaseDynamicLinks.getInstance()
            .createDynamicLink()
            .setLink(baseUrl)
            .setDomainUriPrefix(domain)
            .setIosParameters(new DynamicLink.IosParameters.Builder("com.your.bundleid").build())
            .setAndroidParameters(new DynamicLink.AndroidParameters.Builder("com.your.packageName").build())
            .buildDynamicLink();

    return link.getUri();
}

Kotlin+KTX

fun generateContentLink(): Uri {
    val baseUrl = Uri.parse("https://your-custom-name.page.link")
    val domain = "https://your-app.page.link"

    val link = FirebaseDynamicLinks.getInstance()
            .createDynamicLink()
            .setLink(baseUrl)
            .setDomainUriPrefix(domain)
            .setIosParameters(DynamicLink.IosParameters.Builder("com.your.bundleid").build())
            .setAndroidParameters(DynamicLink.AndroidParameters.Builder("com.your.packageName").build())
            .buildDynamicLink()

    return link.uri
}

هنگامی که یک پیوند پویا دارید ، می توانید یک دکمه اشتراک گذاری به UI خود اضافه کنید که جریان اشتراک گذاری استاندارد پلت فرم را راه اندازی می کند:

سریع

lazy private var shareController: UIActivityViewController = {
  let activities: [Any] = [
    "Learn how to share content via Firebase",
    URL(string: "https://firebase.google.com")!
  ]
  let controller = UIActivityViewController(activityItems: activities,
                                            applicationActivities: nil)
  return controller
}()

@IBAction func shareButtonPressed(_ sender: Any) {
  let inviteController = UIStoryboard(name: "Main", bundle: nil)
    .instantiateViewController(withIdentifier: "InviteViewController")
  self.navigationController?.pushViewController(inviteController, animated: true)
}

هدف-ج

- (UIActivityViewController *)shareController {
  if (_shareController == nil) {
    NSArray *activities = @[
      @"Learn how to share content via Firebase",
      [NSURL URLWithString:@"https://firebase.google.com"]
    ];
    UIActivityViewController *controller = [[UIActivityViewController alloc] initWithActivityItems:activities applicationActivities:nil];
    _shareController = controller;
  }
  return _shareController;
}

- (IBAction)shareLinkButtonPressed:(UIView *)sender {
  if (![sender isKindOfClass:[UIView class]]) {
    return;
  }

  self.shareController.popoverPresentationController.sourceView = sender;
  [self presentViewController:self.shareController animated:YES completion:nil];
}

جاوا

private void onShareClicked() {
    Uri link = DynamicLinksUtil.generateContentLink();

    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setType("text/plain");
    intent.putExtra(Intent.EXTRA_TEXT, link.toString());

    startActivity(Intent.createChooser(intent, "Share Link"));
}

Kotlin+KTX

private fun onShareClicked() {
    val link = DynamicLinksUtil.generateContentLink()

    val intent = Intent(Intent.ACTION_SEND)
    intent.type = "text/plain"
    intent.putExtra(Intent.EXTRA_TEXT, link.toString())

    startActivity(Intent.createChooser(intent, "Share Link"))
}

در این مثال ، رابط کاربری پیش فرض اشتراک گذاری به طور خودکار لیستی از برنامه های اشتراک گذاری پیوند را ارائه می دهد ، بنابراین این چیزی است که می توانید تنها با چند خط کد در برنامه خود تنظیم کنید.

به جای این که کاربر مخاطبین را انتخاب کرده و پیام را در برنامه شما ایجاد کند ، این اقدامات به برنامه ای که از کادر گفتگوی اشتراک گذاری انتخاب می کند ، واگذار می شود. علاوه بر این ، واگذاری اشتراک گذاری به سایر برنامه ها به این معنی است که مجبور نیستید مجوزهای مخاطب را از کاربر بخواهید و به کاربران این امکان را می دهد که از لیست مخاطبین گسترده شده در برنامه انتخابی خود انتخاب کنند. برای تسهیل بهتر به اشتراک گذاری اجتماعی، شما می توانید رسانه های اجتماعی ابرداده پیش نمایش اضافه به پیوند پویا خود را که همراه با لینک در کانال های اصلی اجتماعی نمایش داده خواهد شد.

با این وجود ، گاهی اوقات ، ارسال یک پیوند برهنه بدون متن برای یک ارجاع قانع کننده کافی نیست. با همراهی پیوند با یک پیام کوتاه و در صورت امکان ، ارائه غنی تر ، کاربران می توانند پیشنهاد ارزش ارجاع را هنگام دریافت آن درک کنند:

iOS

rewarded referral screenshotrewarded referral screenshot with share sheet

اندروید

rewarded referral screenshotrewarded referral screenshot with share sheet

اگرچه این پیچیده تر از مثال قبلی است ، اما رویکرد کم و بیش یکسان خواهد بود. در این صفحه یک گرافیک بزرگ با پیشنهاد ارزش دعوت و دکمه هایی برای اشتراک گذاری در کانال های اصلی اجتماعی وجود دارد. در این جریان رابط کاربری افزونگی وجود دارد-برخی از کانال های اشتراک گذاری به صورت جداگانه ارائه می شوند تا امکان سفارشی سازی بیشتر پیام های مربوط به کانال ، مانند افزودن خط موضوع به دعوت نامه های ایمیل ، فراهم شود. در این منوی دعوت ، ما:

  • ایمیل ، پیام متنی ، و دکمه های اشتراک پیوند را کپی کنید و پیام های آنها را به طور مناسب سفارشی کنید. ایمیل شامل یک موضوع است و می تواند شامل بدنه طولانی تری با خطوط ، تصاویر و فضای خالی باشد. متن باید دارای بدنه کوتاهتر با خطوط شکسته اما فضای سفید کم و بدون تصویر باشد. و کپی پیوند فقط باید پیوند را کپی کند و هیچ چیز دیگر.
  • از رابط کاربری اشتراک سیستم برای سایر موارد ، از جمله پیام کوتاه دعوت به همراه پیوند استفاده کنید.
  • پیوند عمیق از طریق طرح URL یا پیوند جهانی به برنامه دیگری که منطق خاصی برای رسیدگی به دعوت نامه های برنامه شما دارد. این امر خارج از مشارکت بین سازمان شما و برنامه دیگر کار نمی کند و احتمالاً برای سازمان های کوچکتر گزینه ای نیست. با این وجود ، برخی از برنامه ها ممکن است رفتار پیوند عمومی/عمیق خود را به صورت عمومی ثبت کنند. ما یک نسخه ساختگی از این را در نمونه خود پیاده سازی می کنیم.

ابتدا نوع محتوای دعوت را تعریف کنید که فقط اطلاعات را در یک دعوتنامه در بر می گیرد و هیچ کارکردی ندارد. به این ترتیب ، می توانید با انواع داده ها شروع کنید و در مورد کد خود در مورد نحوه تقسیم این داده ها به یکدیگر فکر کنید.

سریع

/// The content within an invite, with optional fields to accommodate all presenters.
/// This type could be modified to also include an image, for sending invites over email.
struct InviteContent {

  /// The subject of the message. Not used for invites without subjects, like text message invites.
  var subject: String?

  /// The body of the message. Indispensable content should go here.
  var body: String?

  /// The URL containing the invite. In link-copy cases, only this field will be used.
  var link: URL

}

هدف-ج

/// The content within an invite, with optional fields to accommodate all presenters.
/// This type could be modified to also include an image, for sending invites over email.
@interface InviteContent : NSObject <NSCopying>

/// The subject of the message. Not used for invites without subjects, like text message invites.
@property (nonatomic, readonly, nullable) NSString *subject;

/// The body of the message. Indispensable content should go here.
@property (nonatomic, readonly, nullable) NSString *body;

/// The URL containing the invite. In link-copy cases, only this field will be used.
@property (nonatomic, readonly) NSURL *link;

- (instancetype)initWithSubject:(nullable NSString *)subject
                           body:(nullable NSString *)body
                           link:(NSURL *)link NS_DESIGNATED_INITIALIZER;

- (instancetype)init NS_UNAVAILABLE;

@end

جاوا

/**
 * The content of an invitation, with optional fields to accommodate all presenters.
 * This type could be modified to also include an image, for sending invites over email.
 */
public class InviteContent {

    /**
     * The subject of the message. Not used for invites without subjects, like SMS.
     **/
    @Nullable
    public final String subject;

    /**
     * The body of the message. Indispensable content should go here.
     **/
    @Nullable
    public final String body;

    /**
     * The URL containing the link to invite. In link-copy cases, only this field will be used.
     **/
    @NonNull
    public final Uri link;

    public InviteContent(@Nullable String subject, @Nullable String body, @NonNull Uri link) {
        // ...
    }

}

Kotlin+KTX

/**
 * The content of an invitation, with optional fields to accommodate all presenters.
 * This type could be modified to also include an image, for sending invites over email.
 */
data class InviteContent(
    /** The subject of the message. Not used for invites without subjects, like SMS.  */
    val subject: String?,
    /** The body of the message. Indispensable content should go here.  */
    val body: String?,
    /** The URL containing the link to invite. In link-copy cases, only this field will be used.  */
    val link: Uri
)

تنها قطعه مورد نیاز در اینجا URL است ، بدون آن نمی توانید کاربران را به برنامه خود دعوت کنید. سایر داده ها به وضوح جهت ارسال ایمیل طراحی شده اند ، که در برخی موارد آنها را کمی ناخوشایند می کند-هنگام ارسال دعوت نامه از طریق متن ، ممکن است ابهام همراه پیوند به طور مشابه با موضوع ایمیل خوانده شود ، اما هنگام به اشتراک گذاری در رسانه های اجتماعی پیوند همراه متن ممکن است بیشتر شبیه یک متن ایمیل باشد. شما باید برای آزمایش با این خود را به پیدا کردن بهترین تعادل برای برنامه شما، و اگر شما مطمئن نیستید، شما همیشه می توانید با استفاده از یک سرویس مانند از راه دور پیکربندی به شما اجازه می دهد برای تغییر مقادیر متن پس از راه اندازی برنامه.

سریع

/// A type responsible for presenting an invite given using a specific method
/// given the content of the invite.
protocol InvitePresenter {

  /// The name of the presenter. User-visible.
  var name: String { get }

  /// An icon representing the invite method. User-visible.
  var icon: UIImage? { get }

  /// Whether or not the presenter's method is available. iOS devices that aren't phones
  /// may not be able to send texts, for example.
  var isAvailable: Bool { get }

  /// The content of the invite. Some of the content type's fields may be unused.
  var content: InviteContent { get }

  /// Designated initializer.
  init(content: InviteContent, presentingController: UIViewController)

  /// This method should cause the presenter to present the invite and then handle any actions
  /// required to complete the invite flow.
  func sendInvite()

}

هدف-ج

/// A type responsible for presenting an invite given using a specific method
/// given the content of the invite.
@protocol InvitePresenter <NSObject>

/// The name of the presenter. User-visible.
@property (nonatomic, readonly) NSString *name;

/// An icon representing the invite method. User-visible.
@property (nonatomic, readonly, nullable) UIImage *icon;

/// Whether or not the presenter's method is available. iOS devices that aren't phones
/// may not be able to send texts, for example.
@property (nonatomic, readonly) BOOL isAvailable;

/// The content of the invite. Some of the content type's fields may be unused.
@property (nonatomic, readonly) InviteContent *content;

/// Designated initializer.
- (instancetype)initWithContent:(InviteContent *)content presentingViewController:(UIViewController *)controller;

/// This method should cause the presenter to present the invite and then handle any actions
/// required to complete the invite flow.
- (void)sendInvite;

@end

جاوا

/**
 * Presents the invite using a specific method, such as email or social.
 */
public class InvitePresenter {

    /**
     * The user-visible name of the invite method, like 'Email' or 'SMS'
     **/
    public final String name;

    /**
     * An icon representing the invite method.
     **/
    @DrawableRes
    public final int icon;

    /**
     * Whether or not the method is available on this device. For example, SMS is phone only.
     **/
    public final boolean isAvailable;

    /**
     * The Content of the invitation
     **/
    public final InviteContent content;

    public InvitePresenter(String name, @DrawableRes int icon, boolean isAvailable, InviteContent content) {
        // ...
    }

    /**
     * Send the invitation using the specified method.
     */
    public void sendInvite(Context context) {
        // ...
    }

}

Kotlin+KTX

/**
 * Presents the invite using a specific method, such as email or social.
 */
open class InvitePresenter(
    /** The user-visible name of the invite method, like 'Email' or 'SMS'  */
    val name: String,
    /** An icon representing the invite method.  */
    @param:DrawableRes @field:DrawableRes
    val icon: Int,
    /** Whether or not the method is available on this device. For example, SMS is phone only.  */
    val isAvailable: Boolean,
    /** The Content of the invitation  */
    val content: InviteContent
) {
    /**
     * Send the invitation using the specified method.
     */
    open fun sendInvite(context: Context) {
        // ...
    }
}

اکنون تنها چیزی که باقی می ماند این است که آن را به جزء رابط کاربری دلخواه خود وصل کنید. برای اجرای کامل این جریان دعوت، نمونه در GitHub را ببینید برای IOS و آندروید .

اینها همه روش هایی هستند که به کاربران شما امکان می دهد دعوت نامه هایی را برای دوستان خود ارسال کنند ، که سبک ترین راه حل دعوت است. بسیاری از برنامه های محبوب همچنین با ارسال ایمیل از طریق پشتیبان خود ، که نیاز به ادغام سرویس ارسال نامه دارد ، دعوت نامه ارائه می دهد ، اما تعدادی مزایا را ارائه می دهد که در غیر این صورت تنها با چند اشکال جزئی در دسترس نیستند.

طرفداران:

  • ایمیل هایی را با نشانه گذاری پیچیده فعال می کند که قبل از ارسال توسط کاربر قابل تغییر نیست.
  • ردیابی/تجزیه و تحلیل دقیق تر (یعنی ارسال موفقیت ها و شکست ها در پشتیبان خود) را فعال می کند.

معایب:

  • به احتمال زیاد ایمیل ها به عنوان هرزنامه پرچم گذاری می شوند
  • نیاز به ادغام با سرویس ارسال ایمیل دارد
  • به مجوزهای مخاطبین درون برنامه نیاز دارد

به طور کلی ، ارسال دعوت نامه از طریق سرویس تحویل ایمیل شخصی شما ، هزینه دعوت را با هزینه چند منظوره ، ثابت تر و بالقوه غنی تر می کند.

محتوای پیوندی را در برنامه خود باز کنید

در نهایت ، باید پیوندی را که به برنامه شما ارسال شده است دریافت کنید تا بتوانید محتوای پیوندی را به گیرنده نشان دهید. با استفاده از SDK پیوندهای پویا این کار آسان است:

iOS

در iOS، شما در پیوند پویا دریافت با اجرای application:continueUserActivity:restorationHandler: روش. در دستگیره مرمت، شما می توانید پیوند پویا با تماس گرفتن handleUniversalLink:completion: . اگر یک پیوند پویا به برنامه شما به تصویب رسید، شما می توانید آن را از گرفتن url اموال FIRDynamicLink . مثلا:

هدف-ج

[[FIRDynamicLinks dynamicLinks]
    handleUniversalLink:userActivity.webpageURL
             completion:^(FIRDynamicLink * _Nullable dynamicLink,
                          NSError * _Nullable error) {
      NSString *link = dynamicLink.url;
      BOOL strongMatch = dynamicLink.matchConfidence == FIRDynamicLinkMatchConfidenceStrong;
      // ...
    }];

سریع

FIRDynamicLinks.dynamicLinks()?.handleUniversalLink(userActivity.webpageURL!) { (dynamiclink, error) in
    let link = dynamicLink.url
    let strongMatch = dynamicLink.matchConfidence == FIRDynamicLinkMatchConfidenceStrong
    // ...
}

علاوه بر این، شما باید پاسخ dynamicLinkFromCustomSchemeURL: در application:openURL:options: روش برای دریافت پویا پیوندهای مربوط به برنامه های خود را به عنوان آدرس طرح سفارشی به تصویب رسید. مثلا:

هدف-ج

FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url];
if (dynamicLink) {
  NSString *link = dynamicLink.url;
  BOOL strongMatch = dynamicLink.matchConfidence == FIRDynamicLinkMatchConfidenceStrong;
  // ...
  return YES;
}

سریع

let dynamicLink = FIRDynamicLinks.dynamicLinks()?.dynamicLinkFromCustomSchemeURL(url)
if let dynamicLink = dynamicLink {
  let link = dynamicLink.url
  let strongMatch = dynamicLink.matchConfidence == FIRDynamicLinkMatchConfidenceStrong
  // ...
  return true
}

حالا که شما ارزش link پارامتر، شما می توانید مطالب مرتبط با گیرنده نمایش، و یا پردازش داده ها توسط پارامتر در برخی از راه های دیگر مشخص شده است. یک URL مسیریابی کتابخانه از قبیل JLRoutes می توانید با این کار کمک کند.

اگر شما در حال دریافت لینک نظر گرفته شده برای یک گیرنده خاص، اطمینان حاصل شود که اعتماد به نفس بازی پیوند پویا است strong قبل از اجرای هر گونه منطق کاربر خاص.

اندروید

در آندروید، شما با استفاده از getDynamicLink() روش برای به دست آوردن اطلاعات از پیوند پویا:

جاوا

FirebaseDynamicLinks.getInstance()
        .getDynamicLink(getIntent())
        .addOnCompleteListener(new OnCompleteListener<PendingDynamicLinkData>() {
            @Override
            public void onComplete(@NonNull Task<PendingDynamicLinkData> task) {
                if (!task.isSuccessful()) {
                    // Handle error
                    // ...
                }

                FirebaseAppInvite invite = FirebaseAppInvite.getInvitation(task.getResult());
                if (invite != null) {
                    // Handle invite
                    // ...
                }
            }
        });

Kotlin+KTX

Firebase.dynamicLinks
        .getDynamicLink(intent)
        .addOnCompleteListener { task ->
            if (!task.isSuccessful) {
                // Handle error
                // ...
            }

            val invite = FirebaseAppInvite.getInvitation(task.result)
            if (invite != null) {
                // Handle invite
                // ...
            }
        }

حالا که شما ارزش link پارامتر، شما می توانید مطالب مرتبط با گیرنده نمایش، و یا پردازش داده ها توسط پارامتر در برخی از راه های دیگر مشخص شده است. یک کتابخانه مسیر یابی URL می تواند در این کار کمک کند.